Confused by macro expansion

Discussion of Common Lisp
Post Reply
npolyspace
Posts: 8
Joined: Wed Mar 17, 2010 6:03 pm

Confused by macro expansion

Post by npolyspace » Wed Mar 17, 2010 7:07 pm

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?

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: Confused by macro expansion

Post by nuntius » Wed Mar 17, 2010 10:25 pm

When I run this code, *arglist* is just (y). Perhaps you evaluated (test2 y) twice?

npolyspace
Posts: 8
Joined: Wed Mar 17, 2010 6:03 pm

Re: Confused by macro expansion

Post by npolyspace » Thu Mar 18, 2010 7:30 am

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.

npolyspace
Posts: 8
Joined: Wed Mar 17, 2010 6:03 pm

Re: Confused by macro expansion

Post by npolyspace » Fri Mar 19, 2010 3:57 am

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?

Jasper
Posts: 209
Joined: Fri Oct 10, 2008 8:22 am
Location: Eindhoven, The Netherlands
Contact:

Re: Confused by macro expansion

Post by Jasper » Fri Mar 19, 2010 3:45 pm

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...

gugamilare
Posts: 406
Joined: Sat Mar 07, 2009 6:17 pm
Location: Brazil
Contact:

Re: Confused by macro expansion

Post by gugamilare » Fri Mar 19, 2010 9:13 pm

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.

Post Reply