tags:

views:

97

answers:

1

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))
+6  A: 

A macro expands one form into another form so you cant have a marco return two comeletely independent forms though 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 with to modify:

(expand-mr
 (do 
   (prn 1)
   (mr 2 3)
   (prn 4)))

macros are designed to be safe and as such they cant modify anything outside of there 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 seperate s-expressions it would have to modify it's 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.

Arthur Ulfeldt
Thanks Arthur! I was already expecting that answer, but it's nice to be sure.
Stefan
But can you actually give me an example how a macro returning two independent forms can cause a security problem, but is safe otherwise? I think the scope is still the same.
Stefan
I'm using the term 'safe' loosely sorry about that. I'll edit to expand on that.
Arthur Ulfeldt