'when-let'-like macro that takes custom predicate instead of truth-checking the result?

Intended usage & expansion:

...
(cond-let pos? [delta (- x y)]
  (swap! z + delta)

->

(let [delta (- x y)])
  (when (pos? delta)
    (swap! z + delta))

(cond-let (complement nil?) ...) is functionally equivalent to (when-let ...).

A bare-bones implementation could look like this:

(defmacro cond-let
  [pred [name init-form] & body]
  `(let [~name ~init])
     (when (pred ~name)
       [email protected])

This seems such an obvious, useful shorthand, and I was sure I’d reinvented the wheel, so I did a quick check whether I can find implementations, and/or some established naming convention in the Lisp world, but I haven’t found anything yet. Am I missing something? Is there some other way to express this in a similarly succinct form?

One downside you may run into is that your cond-let does not match any existing Clojure syntax (predicate then binding then body) so you’ll find it challenging to get linters to understand it.

That means it may also be an obstacle for folks new to your codebase to comprehend, compared to the explicit letwhen structure.

1 Like