【发布时间】:2011-02-23 17:07:42
【问题描述】:
如果在 REPL 中我这样做:
(dolist (x (1 2 3))
(print x))
然后我得到一个错误,因为在 (1 2 3) 中,数字 1 不是符号或 lambda expr。 如果我这样做:
(dolist (x (list 1 2 3))
(print x))
然后它工作正常。
我的问题是为什么以下工作:
REPL> (defmacro test (lst)
(dolist (x lst)
(print x)))
=> TEST
REPL> (test (1 2 3))
1
2
3
=>NIL
为什么 dolist 在宏定义中接受 (1 2 3) 而直接在 repl 中却不接受? 假设:
“由于 TEST 是一个宏,它不计算它的参数,所以 (1 2 3) 被原样传递给 dolist 宏。所以 dolist 必须像它在传递 (1 2 3) 时一样抱怨回复”
显然是错误的。但是在哪里?
更新:虽然答案有助于澄清对宏的一些误解,但我的问题仍然存在,我将尝试解释原因:
我们已经确定 dolist 会评估其列表参数(代码块 1、2)。好吧,在宏定义中调用它并且传递给它的列表参数是定义的宏参数之一(代码块 3)时,情况似乎并非如此。更多细节: 宏在调用时不会计算其参数。所以我的测试宏,当它被调用时,将保留列表参数,并在扩展时将它按原样传递给 dolist。然后在扩展时将执行 dolist(我的测试宏定义中没有反引号)。它将以 (1 2 3) 作为参数执行,因为这是传递给它的测试宏调用。那么为什么它不抛出错误,因为 dolist 试图评估它的列表参数,在这种情况下,它的列表参数 (1 2 3) 是不可评估的。我希望这能消除我的困惑。
【问题讨论】:
标签: macros lisp common-lisp