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.