Recreating 'Let' using a Macro in Clojure
Inspired by a good friends recent Gist on how the functionality of the special form
let could be achieved using a little Lambda trickery, I decided to write a simple Macro that would do this transformation.
It is very interesting to see how concepts such as this can be built up from underlying calculus fundamentals.
(defmacro lets [bindings & body] `((fn [~@(take-nth 2 bindings)] ~@body) ~@(take-nth 2 (rest bindings)))) (lets [foo "bar" baz 123] (println foo baz)) ; bar 123
(clojure.walk/macroexpand-all '(lets [foo "bar" baz 123] (println foo baz))) ; ((fn* ([foo baz] (println foo baz))) "bar" 123)
You can see how simple the macro actually is, with the inclusion of only two unquote-splicing actions.
I was hoping to also include some of the guards that are present in the
let macro using
assert-args but sadly this has been made private within the core library.