my-let, from Alex P., uses functions to implement a version of the Clojure special form let:
(defmacro my-let
[bindings & body]
(assert (-> bindings count even?) "Bindings count can only be even.")
`((fn [~@(take-nth 2 bindings)]
~@body)
~@(take-nth 2 (rest bindings))))This isn’t a complete implementation of let, since it doesn’t allow bindings that depend on previous bindings, like in (let [a 1 b (inc a)] ...). And because it’s implemented in terms of functions, it also allows the let to be a recur target (just like loop). It’s pretty cool how little code it takes to write a feature that can do this:
(my-let [{:keys [a b] :or {a :foo}} {:b 2}]
[a b])
;=> [:foo 2]Leaning heavily on pre-existing language features can be a huge help.
Check out Alex’s nice and succinct explanation of the macroexpansion for more detail.