list - 使用两个反引号和逗号,Common Lisp

标签 list syntax common-lisp comma

我正在学习通用 lisp,但在理解两个反引号和两个逗号的用法时遇到了问题:

``(a ,,(+ 1 2))

我的意思是,我不知道为什么它被评估为:
`(A ,3)

而不是这样的:
`(A 3)

我在解释自己,两个逗号都被“消耗”了,以便评估表单前面的两个反引号,所以没有一个逗号应该离开,但仍然有一个。
看起来如何
``(a ,,(+ 1 2))

仅使用 list 和 ' ?

最佳答案

从规范

这就是 Common Lisp HyperSpec 关于嵌套 backticks 的说法。 :

If the backquote syntax is nested, the innermost backquoted form should be expanded first. This means that if several commas occur in a row, the leftmost one belongs to the innermost backquote.



R5RS 方案规范还包括有关 backticks 的这些详细信息。 :

Quasiquote forms may be nested. Substitutions are made only for unquoted components appearing at the same nesting level as the outermost backquote. The nesting level increases by one inside each successive quasiquotation, and decreases by one inside each unquotation.



还要记住,每次评估只有一个反引号被折叠,就像常规引用一样,它不是递归的。

行动规则

要了解这三个细节如何相互作用,让我们稍微扩展一下您的示例。这个表情...
``(a ,,(+ 1 2) ,(+ 3 4))

对此进行评估(以 SBCL 表示法):
`(A ,3 ,(+ 3 4))
  • 左边的反引号被折叠了,所以它是 (+ 1 2)被匹配的逗号转义(根据 HyperSpec,第二个逗号)。
  • 另一方面,(+ 3 4)没有足够的逗号来扩展(这是 R5RS 提到的)。
  • 只有一个反引号被折叠,因为反引号不会递归扩展。

  • 扩展两个逗号

    为了摆脱另一个反引号,需要另一个级别的评估:
    (eval ``(a ,,(+ 1 2) ,(+ 3 4)))
    

    两个反引号都消失了,我们只剩下一个简单的列表:
    (A 3 7)
    

    关于list - 使用两个反引号和逗号,Common Lisp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7549550/

    相关文章:

    common-lisp - 打印原始路径名结构

    vim - 无法在 Vim 中自动设置语法高亮

    c# - 带有 "?"和 "??"的代码是什么意思?

    common-lisp - lisp 中的破坏性排序

    python - 加速python中的代码块

    jQuery-Prototype 无冲突且语法正确

    common-lisp - Lisp 中如何判断文件类型

    r - 将 ifelse() 创建的变量添加到数据框列表

    Python:元组和列表之间的差异和相似之处

    c# - 如何将 Array.Sort 应用于 Collection<T>?