Lisp CHLS";最里面的反引号格式应首先展开“;意思
声明“如果反引号语法是嵌套的,则应首先展开最里面的反引号形式。这意味着,如果一行中出现多个逗号,则最左边的逗号属于最里面的反引号。” 但是当我在SBCL中计算以下嵌套反引号表达式时Lisp CHLS";最里面的反引号格式应首先展开“;意思,lisp,common-lisp,Lisp,Common Lisp,声明“如果反引号语法是嵌套的,则应首先展开最里面的反引号形式。这意味着,如果一行中出现多个逗号,则最左边的逗号属于最里面的反引号。” 但是当我在SBCL中计算以下嵌套反引号表达式时 `(outer `(inner ,@(no ,@(list 'cat 'dog)))) ; expression P 我明白了 表达式p的外部后引形式(而不是内部后引形式)似乎在以下意义上展开: 外部背景消失,而内部背景在评估后仍然存在 只有与外部反勾号级别对应的逗号完成了拼接工作(表达式P中的第二个逗号)
`(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)))
- 删除最外层的反勾号字符
- 然后,用评估结果替换与最外层反引号处于同一级别的下列表单的逗号(请参见了解同一级别的含义)(同时,删除这些逗号)
- 然后,通过将评估结果拼接到最外层反引号所在的位置,替换与最外层反引号处于同一级别的下列表格中的逗号(同时,删除最外层反引号中的逗号)
- 答案在
帮助我弄清楚发生了什么。我将在这个答案的基础上,应用到这个问题上
这里我们有两种方法来推理嵌套的反引号形式。一种方法,我称之为替换解释,就是对于双嵌套的反引号形式,对该形式的求值是
,@',@
,',@
,,@
,@,@
对于前两种情况,复杂的是必须在引号字符之前拼接列表。在引号字符之前拼接是什么意思?它没有任何意义。但是如果您将“某物”
视为(引号某物)
,那么你可以说在引号字符之前拼接一个元素列表是有意义的,它意味着引用那个元素。如果你像这样修补替换解释,它会给出与实际结果一致的结果
对于后两种情况,复杂的是必须在逗号字符(或逗号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)))
,@',@
,',@
,,@
,@,@