defmacro形式参数列表中`(& rest xs)`和`xs`之间的区别

时间:2015-12-30 09:04:42

标签: macros pattern-matching common-lisp practical-common-lisp

在Practical Common Lisp的Chapter 8,宏:定义你自己,我们定义一个宏with-gensyms如下:

(defmacro with-gensyms ((&rest names) &body body)
  `(let ,(loop for n in names collect `(,n (gensym)))
    ,@body))

(&rest names)的目的是什么?如果我们用names替换它,效果似乎是一样的。在这两种情况下,我们都会将符号列表传递给“gensym-ed”。

1 个答案:

答案 0 :(得分:9)

区别:

(&rest names)仅匹配列表。当某人正在使用宏时,错误来自宏扩展器:

  在SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR上调用

调试器:

     解析DEFMACRO WITH-GENSYMS的参数时出现

错误:

     

伪造子列表A以满足lambda-list (&REST NAMES)

names匹配任何内容。当有人使用没有列表的宏时,错误来自LOOP宏,需要一个列表:

  在TYPE-ERROR上调用了

调试器:值A的类型不是LIST

因此,您可以获得更好的早期错误。