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.

因此你得到一个更好更早的错误。