defmacro 形式参数列表中`(&rest xs)` 和`xs` 的区别
Difference between `(&rest xs)` and `xs` in defmacro formal argument list
在 Practical Common Lisp 的 Chapter 8, Macros: Defining Your Own 中,我们定义了一个宏 with-gensyms
如下:
(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body))
(&rest names)
的目的是什么?如果我们只用 names
替换它,效果似乎是一样的。在这两种情况下,我们都将符号列表传递给 "gensym-ed".
区别:
arglist ((&rest names) &body body)
中的 (&rest names)
仅匹配列表。当有人将宏与其他东西一起使用时,错误来自宏扩展器:
debugger invoked on a SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR
:
error while parsing arguments to DEFMACRO WITH-GENSYMS
:
bogus sublist A
to satisfy lambda-list (&REST NAMES)
names
匹配任何内容。当有人使用没有列表的宏时,错误来自 LOOP 宏,它需要一个列表:
debugger invoked on a TYPE-ERROR
: The value A
is not of type LIST
.
因此你得到一个更好更早的错误。
在 Practical Common Lisp 的 Chapter 8, Macros: Defining Your Own 中,我们定义了一个宏 with-gensyms
如下:
(defmacro with-gensyms ((&rest names) &body body)
`(let ,(loop for n in names collect `(,n (gensym)))
,@body))
(&rest names)
的目的是什么?如果我们只用 names
替换它,效果似乎是一样的。在这两种情况下,我们都将符号列表传递给 "gensym-ed".
区别:
arglist((&rest names) &body body)
中的 (&rest names)
仅匹配列表。当有人将宏与其他东西一起使用时,错误来自宏扩展器:
debugger invoked on a
SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR
:error while parsing arguments to
DEFMACRO WITH-GENSYMS
:bogus sublist
A
to satisfy lambda-list(&REST NAMES)
names
匹配任何内容。当有人使用没有列表的宏时,错误来自 LOOP 宏,它需要一个列表:
debugger invoked on a
TYPE-ERROR
: The valueA
is not of typeLIST
.
因此你得到一个更好更早的错误。