Reputation: 582
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?
Upvotes: 4
Views: 328
Reputation: 1671
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.
Upvotes: 7