14.5.4 Evaluating Macro Arguments in Expansion

Another problem can happen if the macro definition itself evaluates any of the macro argument expressions, such as by calling eval (see Eval). You have to take into account that macro expansion may take place long before the code is executed, when the context of the caller (where the macro expansion will be evaluated) is not yet accessible.

Also, if your macro definition does not use lexical-binding, its formal arguments may hide the user’s variables of the same name. Inside the macro body, the macro argument binding is the most local binding of such variable, so any references inside the form being evaluated do refer to it. Here is an example:

(defmacro foo (a)
  (list 'setq (eval a) t))
(setq x 'b)
(foo x) → (setq b t)
     ⇒ t                  ; and b has been set.
;; but
(setq a 'c)
(foo a) → (setq a t)
     ⇒ t                  ; but this set a, not c.

It makes a difference whether the user’s variable is named a or x, because a conflicts with the macro argument variable a.

Also, the expansion of (foo x) above will return something different or signal an error when the code is compiled, since in that case (foo x) is expanded during compilation, whereas the execution of (setq x 'b) will only take place later when the code is executed.

To avoid these problems, don’t evaluate an argument expression while computing the macro expansion. Instead, substitute the expression into the macro expansion, so that its value will be computed as part of executing the expansion. This is how the other examples in this chapter work.