From: Caelan Burris on
> 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
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