Reputation: 3
I have a next piece of code:
(in-package :cl-user)
(defmacro test0 (form)
(format t "test0: Expander phase: ~s" form)
`(format t "test0: Expansion phase: ~s" ,form))
(defmacro test1 (form)
(format t "test1: Expander phase: ~s" form)
(test0 form)
`(format t "test1: Expansion phase: ~s" ,form))
Common Lisp implementation: "SBCL 1.3.16"
.
Results of (compile-file "source.lisp")
:
; compiling (IN-PACKAGE :CL-USER)
; compiling (DEFMACRO TEST0 ...)
; compiling (DEFMACRO TEST1 ...)test0: Expander phase: FORMtest0: Expander phase: FORM
Results of (load "source.lisp")
:
; #<PACKAGE "COMMON-LISP-USER">
; TEST0
test0: Expander phase: FORM
; TEST1
And I just can't understand next things:
Why is nested subform (test0 form)
expanded and processed in the definition of test1
macro? Why isn't it processed in the macro call instead?
Where is Common Lisp standard specify such a behavior? eval-when
? Files compilation? Forms evaluation?
Finally, why is "test0: Expander phase: FORM"
printed twice during compilation(compile-file
) and only once during evaluation(load
)?
I think the answers are pretty obvious but I can't find them out.
Upvotes: 0
Views: 219
Reputation: 60004
A macro is a function which operates on code.
Since in Lisp code is just a
list
,
macro functions look like ordinary functions.
Your defmacro test1
is treated as a definition of a function, so all the code is processed appropriately and (test0 form)
is macroexpanded when the SBCL compiles defmacro test1
. This answers q1.
load
"sequentially executes
each form it encounters", so to answer your q2, you need to read 3.1
Evaluation, specifically,
3.1.2.1.2.2 Macro Forms.
As for how many times a macro is expanded, this is not specified by the
standard (an implementation can expand it on every call of the user
function!), and this is a reason why it is not a good idea for a macro
to have side effects (e.g., to do output).
In your case, loading requires expansion when test1
is defined.
Compilation expands when it defines test1
and then again when it
compiles it.
Remember, defmacro
arranges that the macro can be used in the
following code (including in itself recursively), so is has to be defined immediately.
Upvotes: 5