Page 1 of 1
Confused by macro expansion
Posted: Wed Mar 17, 2010 7:07 pm
by npolyspace
I am confused about macro expansion.
For example, the following code
(defvar *arglist* nil)
(defmacro test2(x)
(progn
(push x *arglist*)
`(setf ,x 7)))
(test2 y)
*arglist*
sets *arglist* to '(y y)
Why does the push appear to get evaluated twice?
Re: Confused by macro expansion
Posted: Wed Mar 17, 2010 10:25 pm
by nuntius
When I run this code, *arglist* is just (y). Perhaps you evaluated (test2 y) twice?
Re: Confused by macro expansion
Posted: Thu Mar 18, 2010 7:30 am
by npolyspace
I just tried it again. It seems like I only get the double push on sbcl (linux 1.0.33). I don't seem to get it on cmucl, clisp or ccl.
Re: Confused by macro expansion
Posted: Fri Mar 19, 2010 3:57 am
by npolyspace
I posted this as a bug to sbcl, and was told:
Strictly speaking IIRC, macros are allowed to be expanded multiple
times, what is going on here seems unintentional.
Does anyone here know where the specification says macros can be expanded multiple times?
Re: Confused by macro expansion
Posted: Fri Mar 19, 2010 3:45 pm
by Jasper
To be honest, i think not requiring macros to be run only once is fair enough, but maybe then there should be a *test-me* special var too, testing the user that he isn't using unspecified behavior; randomizing the number of times the macro is called...
Re: Confused by macro expansion
Posted: Fri Mar 19, 2010 9:13 pm
by gugamilare
Well, I think that good macros are idempotent, which means that several expansions of the same macro will not create different outputs. The programmer using this macro might want to compile or load some file several times (while testing or debugging) or use the REPL redefining a function several times (changing little bits).
In this case, for instance, instead of push, I think a pushnew is much more adequate. I know this was just an illustration, but that is the general idea. But SBCL expanding macros twice does seem very wrong.