【问题标题】:Difference between `(&rest xs)` and `xs` in defmacro formal argument listdefmacro形式参数列表中`(&rest xs)`和`xs`之间的区别
【发布时间】:2016-04-04 05:36:46
【问题描述】:

在 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”的符号列表。

【问题讨论】:

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


    【解决方案1】:

    区别:

    (&rest names) 在 arglist 中 ((&rest names) &body body) 仅匹配列表。当有人将宏与其他东西一起使用时,错误来自宏扩展器:

    SB-KERNEL::DEFMACRO-BOGUS-SUBLIST-ERROR 上调用的调试器:

    解析DEFMACRO WITH-GENSYMS的参数时出错:

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

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

    TYPE-ERROR 上调用的调试器:值A 不是LIST 类型。

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

    【讨论】:

    • 所以当我们期望args 是一个列表时使用((&rest args)) 是惯用的吗?
    • @TianxiangXiong:你不想使用更具体的结构吗?
    猜你喜欢
    • 1970-01-01
    • 2010-11-14
    • 2013-06-04
    • 2022-08-15
    • 2020-02-15
    • 1970-01-01
    • 2011-03-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多