在他的书ANSI Common Lisp,第320页中,Paul Graham写道macrolet
:"与flet
一样,本地宏可能不会互相调用。 #34;
也许我误解了这一点,但我无法想到它可能是真的。宏不会相互调用,而是互相扩展,宏扩展的性质是这样的,它一直持续到范围内定义的所有宏都被扩展为止。
以下代码在我尝试使用Common Lisp的每个实现中都不同意Graham:
(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)
格雷厄姆的陈述是错误的吗?
答案 0 :(得分:7)
由macrolet
定义的宏扩展可以使用在同一macrolet
中定义的不同宏。由macrolet
定义的宏直接使用在同一macrolet
中定义的不同宏是不正确的。例如:
(macrolet ((jump (x) `(car ,x))
;; Okay since skip expands into jump.
(skip (x) `(jump ,x)))
(skip '(1 2 3)))
=> 1
而不是
(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.