【发布时间】:2017-06-10 09:47:30
【问题描述】:
这是关于“编译和宏扩展”主题的引用,来自Common Lisp: A gentle introduction to symbolic computation一书。
(defmacro bad-announce-macro ()
(format t "~%Hi mom!"))
(defun say-hi ()
(bad-announce-macro))
> (compile 'say-hi)
Hi, mom!
SAY-HI
> (say-hi)
NIL
在上面的例子中,宏被扩展为过程的一部分
编译SAY-HI。所以编译器说‘‘Hi, mom!’’的结果
宏是 NIL,所以这就是编译到 SAY-HI 主体中的内容。什么时候
我们调用编译后的SAY-HI 函数,它什么也没说,因为宏有
被它的扩展所取代。
在这句话中,作者说
宏已被其扩展替换
好的,所以它不应该至少显示打印的 "Hi mom!" 吗?因为虽然宏没有返回任何东西,但它仍然被某些东西取代(它是扩展)。根据代码,我假设
当一个函数在编译后被调用时,在它的主体中调用的所有宏都被扩展为 它们返回的结果 ,而不是它们自己的主体中的任何内容。
我不确定这是否正确。而这样做的原因也不清楚。
【问题讨论】:
-
宏的展开就是宏的返回值。由于宏返回
NIL,它的扩展是NIL,这就是它在SAY-HI函数中的替换。 -
@jkiiski : 但是为什么函数打印
"Hi mom!"直到它没有被编译? -
宏在编译代码时被展开(宏的副作用发生在展开过程中)。在此之前,无论您使用什么实现,它都是解释代码(并且在调用函数时宏会动态扩展)。
-
所以,无论何时展开宏,我都会看到它的副作用。并且在编译的情况下只展开一次,之后的每次调用都会使用宏的结果。而在解释代码的情况下,每次调用时都会对其进行扩展。对吗?
-
是的,没错。
标签: compilation macros common-lisp