This solution certainly looks like it would work.

After pondering it for a while, though, I think I would pass on this solution. It’s doing more work than necessary. First, it has to be wrapped up in a new list, which has a (possibly minimal) cost, and finally you have to unwrap it from the list filter returns using first, which also has a (probably very minimal) cost.

]]>user=> (defn check? [v] (= v 5))

#’user/check?

user=> (defn some-computation [x y z] (+ x y z))

#’user/some-computation

user=> (filter check? (list (some-computation 1 3 1) 7))

(5)

user=> (first (filter check? (list (some-computation 1 3 1) 7)))

5

(if-let [n-shared (if (empty? shared-items) false (count shared-items))]

(let […])

0)

I check for a condition with if, within the if-let, if I see the condition, I return false, which hits the false return condition. Otherwise I bind and move into the next let block.

]]>What about starting from if-let and adding a :when guard (which is evaled with the let val):

(defmacro guard-let

[[v f _ guard?] then else]

`(let [~v ~f]

(if (~guard? ~v)

~then

~else)))

(defn add-or-even [x y]

(guard-let [val (+ x y) :when odd?] val :even))

(add-or-even 1 2)

> 3

(add-or-even 2 2)

>:even

Could easily do a form that implicitly named val and returned it when the guard is true so it would look like: (guard-let [(+ x y) :when odd?] :even) and then you could let go of the let binding form and just do something like: (guard (+ x y) :when odd? :even) which is pretty much what you have but orders the computation better and echoes the (for) style :when guard.

]]>