Let's define a function, the body of which contains the macro, which will be expanded at some unspecified time and will use a global dynamic value of *test* during this process.
> (defvar *test* nil)
> (defmacro body ()
`(print ,*test*))
> (defun test ()
(body))
> (test)
NIL
But what if I want to bind *test* to, say, 1 during function definition, so that the macroexpansion operated with this binding in effect and the call to test produced 1 instead of NIL.
Just wrapping defun in let doesn't work:
> (let ((*test* 1))
(defun test ()
(body)))
> (test)
NIL
Probably, it is related to this line in Hyperspec:
defun is not required to perform any compile-time side effects
But are there any other ways to do that?