【问题标题】:Using two backquotes and commas, Common Lisp使用两个反引号和逗号,Common Lisp
【发布时间】:2011-11-24 20:38:33
【问题描述】:

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

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

我的意思是,我不知道为什么它被评估为:

`(A ,3)

而不是类似的东西:

`(A 3)

我在解释自己,两个逗号都被“消耗”了,以便评估表单前面的两个反引号,所以没有一个逗号应该离开,但仍然有一个。 会是什么样子

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

仅使用列表和 ' ?

【问题讨论】:

    标签: list syntax common-lisp comma


    【解决方案1】:

    根据规格

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

    如果反引号语法是嵌套的,最里面的反引号形式应该首先展开。这意味着如果连续出现多个逗号,则最左边的一个属于最里面的反引号。

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

    准引用形式可以嵌套。仅对出现在与最外层反引号相同的嵌套级别的未引用组件进行替换。嵌套级别在每个连续的 quasiquotation 内增加一个,在每个 unquotation 内减少一个。

    另外请记住,每次评估只会折叠一个反引号,就像常规引用一样,它不是递归的。

    行动规则

    要了解这三个细节如何相互作用,让我们稍微扩展一下您的示例。这个表情……

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

    对此进行评估(以 SBCL 表示法):

    `(A ,3 ,(+ 3 4))
    
    1. 左反引号被折叠,因此 (+ 1 2) 被匹配的逗号(根据 HyperSpec,第 2nd 逗号)转义。
    2. 另一方面,(+ 3 4) 没有足够的逗号来扩展(这是 R5RS 提到的)。
    3. 只有一个反引号被折叠,因为反引号不会递归展开。

    扩展两个逗号

    为了摆脱另一个反引号,需要另一个级别的评估:

    (eval ``(a ,,(+ 1 2) ,(+ 3 4)))
    

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

    (A 3 7)
    

    【讨论】:

    • 感谢您进一步举例说明一个更加“病态”的案例(尽管我认为它很棒,而不是病态)。
    • 另外,要了解“应首先解释内部反引号形式”和“正在执行的规则”是如何相关的,请参阅stackoverflow.com/questions/18008099/…
    【解决方案2】:

    不,两个逗号都用完了。有两级引用和两级逗号。现在有一级引号和一级逗号。事实上,GNU Common Lisp (2.44.1) 将您的表达式计算为

    (list 'a 3)
    

    这完全一样

    `(a ,3)
    

    但更明确地“评估”了两个逗号。

    【讨论】:

      猜你喜欢
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 1970-01-01
      • 2015-04-30
      • 1970-01-01
      相关资源
      最近更新 更多