From: Caelan Burris on 11 Aug 2010 11:47 > Really? I don't see how that has anything to do with the difference > between your FOO and BAR macros. If macro arguments were evaluated, > you'd expect both of them to report an error, since IF has no value. Okay, I was missing several things, but the non-evaluation bit made it all click. I was interpreting the statement that macros "return some new Lisp form, called the expansion of the macro call" in section 8 of CLTL less literally than intended. But looking at the contents of macro arguments and playing with LIST in macro bodies helped a lot.
From: Rob Warnock on 11 Aug 2010 21:49
Caelan Burris <caelanburris(a)gmail.com> wrote: +--------------- | Okay, I was missing several things, but the non-evaluation bit made it | all click. I was interpreting the statement that macros "return some | new Lisp form, called the expansion of the macro call" in section 8 of | CLTL less literally than intended. But looking at the contents of | macro arguments and playing with LIST in macro bodies helped a lot. +--------------- You may also want to experiment with MACROEXPAND and/or MACROEXPAND-1, e.g.: > (defmacro foo (x y z) (let ((tmp (+ x y))) `(* ,tmp ,z))) FOO > (macroexpand '(foo 2 3 (/ 17 5.0))) (* 5 (/ 17 5.0)) T > So the "*" in the macro and the "/" in the 3rd argument will be called at runtime, whereas the "+" in the macro was called at macroexpansion time [which is the same as compile time for files which are COMPILE-FILE'd]. -Rob p.s. Many (most?) implementations have a non-standard extension which expands even more agressively than MACROEXPAND, often called MACROEXPAND-ALL or similar, which can be useful in some situations. It's often off in a corner somewhere, maybe in a special debug package or something. E.g., in CMUCL it's WALKER:MACROEXPAND-ALL. ----- Rob Warnock <rpw3(a)rpw3.org> 627 26th Avenue <URL:http://rpw3.org/> San Mateo, CA 94403 (650)572-2607 |