In his book ANSI Common Lisp, p.320, Paul Graham writes of macrolet
: "Like flet
, the local macros may not call one another."
Maybe I misunderstand this but I can't think of any way in which it could be true. Macros do not call each other so much as expand into each other and the nature of macro expansion is such that it continues until all macros defined in the scope have been expanded away.
Code such as the following disagrees with Graham in every implentation of Common Lisp I've tried:
(macrolet ((jump (x) `(car ,x))
(skip (x) `(jump ,x))
(hop (x) `(skip ,x)))
(hop '(1 2 3)))
=> 1
(macrolet ((yin (n x)
(if (zerop n)
`(cdr ,x)
`(yang ,(1- n) ,x)))
(yang (n x)
(if (zerop n)
`(car ,x)
`(yin ,(1- n) ,x))))
(yin 6 '(1 2 3)))
=> (2 3)
Is Graham's statement in error?
Macros can't be recursive.
21.5. 1 Macro Expansion Is Recursive Notice that when sendmail recursively expands a macro, it does so one macro at a time, always expanding the leftmost macro first.
It is okay for a macro defined by macrolet
to expand into the use of a different macro defined in the same macrolet
. It is incorrect for a macro defined by macrolet
to directly use a different macro defined in the same macrolet
. For example:
(macrolet ((jump (x) `(car ,x))
;; Okay since skip expands into jump.
(skip (x) `(jump ,x)))
(skip '(1 2 3)))
=> 1
as opposed to
(macrolet ((jump (x) `(car ,x))
;; Wrong since skip uses jump directly.
(skip (x) (jump x)))
(skip '(1 2 3)))
=> Error: The function COMMON-LISP-USER::JUMP is undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With