Reputation: 71
Is it possible to write a macro in Clojure that generate more than one value or expression? For me it looks like it's not possible, at least not by using the syntax quote template `(..).
e.g. from: [1 4]
via [1 (mr 2 3) 4]
to [1 2 3 4]
or from:
(do
(prn 1)
(prn 4))
via:
(do
(prn 1)
(mr 2 3)
(prn 4))
to:
(do
(prn 1)
(prn 2)
(prn 3)
(prn 4))
Upvotes: 7
Views: 546
Reputation: 91554
A macro expands one form into another form, so you can't have a macro return two completely independent forms. However, you can have it return compound forms like do
statements that do a bunch of things.
(defmacro foo [n]
`(do ~@(map #(list println %) n)))
For your example above you can put the macro around the form you wish to modify:
(expand-mr
(do
(prn 1)
(mr 2 3)
(prn 4)))
macros are designed to be safe and as such they can't modify anything outside of their own scope. Currently a macro gets an s-expression, and changes it into another more useful or helpful s-expression. In order for a macro to return two separate s-expressions it would have to modify its enclosing expression. The syntax would have to be radically different and I'm not clear how this would be done with s-expressions. The solution of this is to expand the scope of the macro to include everything it needs to modify.
Upvotes: 10