I am currently reading Structure and Interpretation of Computer Programs and stumbled upon the mention that closures could be used to implement the let-function. Next thing I knew, the Clojure REPL was running …
The First Try
1 2 3 4 5 6 7 8 9 10 | |
The basic idea is to generate a closure via the fn-function, set the binding names as parameter names and invoke the function with the binding values.
As you can see the basic binding functionality is working. But there are still two problems. First you can only bind primitive values otherwise the flatten-function would destroy the passed in nested lists. Second you can not access a preceding binding in a succeeding one.
1 2 3 4 5 6 7 | |
The Second Try
To sort out the problems I switched to nested closures:
1 2 3 4 5 6 7 8 9 10 11 12 | |
The idea behind this solution is to generate nested closures so that preceding bindings can be accessed via the parameter of the outer closures. As it turns out both problems get fixed by this approach.
The main challenge in writing the second macro was the (eval ~@body) part. In the example the form (* a b) will be wrapped in another list because body is an optional parameter. To get rid of the extra parentheses unquote-splicing ~@ could be used. Sadly, well actually it makes sense, ~@ can only be used in already escaped lists. Just wrapping another list around wouldn’t make any sense, ~@ just got rid of it. After a long time of try and error I finally found the eval solution.
Conclusion
This little example demonstrates once again how powerful Lisp / Clojure and Macros can be. And don’t forget to read SICP.

I just described the basic idea behind the solution. If you have any further questions feel free to contact me or write a comment.

