Confused by macro expansion
-
- Posts: 8
- Joined: Wed Mar 17, 2010 6:03 pm
Confused by macro expansion
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?
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
When I run this code, *arglist* is just (y). Perhaps you evaluated (test2 y) twice?
-
- Posts: 8
- Joined: Wed Mar 17, 2010 6:03 pm
Re: Confused by macro expansion
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.
-
- Posts: 8
- Joined: Wed Mar 17, 2010 6:03 pm
Re: Confused by macro expansion
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?
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
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...
-
- Posts: 406
- Joined: Sat Mar 07, 2009 6:17 pm
- Location: Brazil
- Contact:
Re: Confused by macro expansion
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.
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.