Lisp CHLS";最里面的反引号格式应首先展开“;意思

Lisp CHLS";最里面的反引号格式应首先展开“;意思,lisp,common-lisp,Lisp,Common Lisp,声明“如果反引号语法是嵌套的,则应首先展开最里面的反引号形式。这意味着,如果一行中出现多个逗号,则最左边的逗号属于最里面的反引号。” 但是当我在SBCL中计算以下嵌套反引号表达式时 `(outer `(inner ,@(no ,@(list 'cat 'dog)))) ; expression P 我明白了 表达式p的外部后引形式(而不是内部后引形式)似乎在以下意义上展开: 外部背景消失,而内部背景在评估后仍然存在 只有与外部反勾号级别对应的逗号完成了拼接工作(表达式P中的第二个逗号)

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

但是当我在SBCL中计算以下嵌套反引号表达式时

`(outer `(inner ,@(no ,@(list 'cat 'dog))))  ; expression P
我明白了

表达式p的外部后引形式(而不是内部后引形式)似乎在以下意义上展开:

  • 外部背景消失,而内部背景在评估后仍然存在
  • 只有与外部反勾号级别对应的逗号完成了拼接工作(表达式P中的第二个逗号)

CHLS说“最里面的反引号形式应该首先展开”是什么意思?

我同意这句话可能会让人困惑,但我认为理解它的关键是“如果一行中出现几个逗号”,指向最里面的逗号形式应该首先展开的解释。从某种意义上说,这是必须发生的事情。毕竟,考虑一下你的例子:

`(outer `(inner ,@(no ,@(list 'cat 'dog))))
考虑两种评估策略

  • 一个选项是首先尝试评估
    ,@(no…
    。然而,这意味着评估表单

    (no ,@(list 'cat 'dog))
    
    但这是不好的,因为现在我们将遇到
    ,@(列出“猫”狗)
    ,而不附带反引号。(是的,在更大的范围内,有一个倒引号,但不是在评估时,只是
    (否,@(列出“猫”狗))

  • 计算
    (外部…
    时的另一个选项是取消引用并拼接最内部的逗号形式,这意味着计算

    (list 'cat 'dog)
    
    这完全没有问题。完成此操作后,我们得到了您获得的表格:

    (outer `(inner ,@(no cat dog)))
    
为了让其他读者了解这个答案,这里有一些相关的问题:

    • 答案在 帮助我弄清楚发生了什么。我将在这个答案的基础上,应用到这个问题上

      这里我们有两种方法来推理嵌套的反引号形式。一种方法,我称之为替换解释,就是对于双嵌套的反引号形式,对该形式的求值是

      • 删除最外层的反勾号字符
      • 然后,用评估结果替换与最外层反引号处于同一级别的下列表单的逗号(请参见了解同一级别的含义)(同时,删除这些逗号)
      • 然后,通过将评估结果拼接到最外层反引号所在的位置,替换与最外层反引号处于同一级别的下列表格中的逗号(同时,删除最外层反引号中的逗号)
      另一种方法,我将称之为等价性解释,就是我应该用等价的非反引号形式重新解释反引号形式,就像在CLHS链接中一样,对于双重嵌套的反引号形式,我应该在重新解释最外层的反引号形式之前,重新解释最内层的反引号形式

      替换解释明确指定的唯一一件事是如何评估反向报价表单。反向报价表单如何等效于非反向报价表单只是间接指定了其评估工作方式的结果

      等价性解释明确指定的唯一一件事是反向报价表单如何等效于非反向报价表单。反向报价表单的计算方式仅间接指定为其等效非反向报价表单的计算方式的结果

      SBCL计算表达式p的方法很容易从替换解释中解释。但也可以从等价解释中解释。为了了解原因,我们首先通过示例A和示例B进行研究

      一些约定:我使用~表示“上一个表达式相当于下一个表达式”。我使用~>表示“上一个表达式的计算结果等于或等于下一个表达式”。通过“等效于”,我的意思可能被解释为“与CLHS链接中的意思相同”

      示例A(简单的反报价表):

      示例B(逗号位于较深位置时):

      示例C(表达式p)

      因此,替代解释与迄今为止的等效解释是一致的

      这两种解释是否始终兼容?替换解释有一些复杂性,如果我正确阅读CLHS链接,那么等效解释似乎是CLHS的一部分。因此,等效解释似乎是真正的交易,替换解释只是一种方便的幻觉

      替换解释的复杂度是什么?我已经通过了替换解释的所有双嵌套反引用示例,大多数示例(四个除外)都没有复杂度。对于大多数示例,替换解释有效,并且与实际结果一致

      出现并发症的四个例子是:

      ,@',@
      ,',@
      ,,@
      ,@,@
      
      对于前两种情况,复杂的是必须在引号字符之前拼接列表。在引号字符之前拼接是什么意思?它没有任何意义。但是如果您将
      “某物”
      视为
      (引号某物)
      ,那么你可以说在引号字符之前拼接一个元素列表是有意义的,它意味着引用那个元素。如果你像这样修补替换解释,它会给出与实际结果一致的结果

      对于后两种情况,复杂的是必须在逗号字符(或逗号at)之前拼接列表。在逗号字符之前拼接是什么意思?它什么意思都没有。但是如果您说“简单地拼接列表,然后在每个插入的元素前面放一个逗号(或逗号at)”然后,这种修补的替换解释给出了与实际结果一致的结果

      Emacs Lisp注意:对于最后两个,
      `(open ,@(list 'cat 'dog))
      ;; ~
      (append (list `open)
              (list 'cat 'dog)
              nil)
      ;; ~
      (append (list 'open)
              (list 'cat 'dog)
              nil)
      ;; ~>
      (open cat dog)
      
      `(beg (open ,@(list 'cat 'dog)))
      ;; ~
      (append (list `beg)
              (list `(open ,@(list 'cat 'dog)))
              nil)
      ;; ~>
      (beg (open cat dog))
      
      `(outer
        `(inner ,@(no ,@(list 'cat 'dog))))
      ;; ~
      `(outer
        '(append
          (list `inner)
          (no ,@(list 'cat 'dog))
          nil))
      ;; ~>
      (outer
       '(append
         (list `inner)
         (no cat dog)
         nil))
      ;; ~
      (outer
       `(inner ,@(no cat dog)))
      
      ,@',@
      ,',@
      ,,@
      ,@,@