为什么点后面的非拼接逗号拼接列表模板中的列表?

时间:2016-07-13 21:06:59

标签: common-lisp

第68页,来自Peter Norvig的人工智能编程范例,我们有以下代码:

test               -> (a test)
`(this is ,test)   -> (this is (a test))
`(this is ,@test)  -> (this is a test)

到目前为止一切顺利。拼接逗号会爆炸外括号。但是这个代码没有在书中解释:

`(this is . ,test) -> (this is a test)

它是如何运作的?引擎盖下发生了什么?

2 个答案:

答案 0 :(得分:3)

来自[反引号] [1]的CLHS部分:

  

`(x1 x2 x3 ... xn . ,form)可能被解释为

    (append [ x1] [ x2] [ x3] ... [ xn] form)
     

其中括号表示如上所述的xj转换。

所以

`(this is . ,test)

相当于:

(append '(this) '(is) test)

相当于:

(append '(this is) test)

因此,它会创建一个以this is开头的列表,尾部是test的内容。

这与用于创建虚线列表的语法相似:

'(1 2 . 3)

因为3放在列表中最后CDR的{​​{1}}中,而不是将CONS放在正确的列表中。当你使用反引号时,它会将整个列表放在那个地方,所以它就像:

NIL

相同
'(this is . (a test))

答案 1 :(得分:2)

要了解发生了什么,我们必须重新审视如何在常见的lisp中实现列表。列表是一系列以nil值结尾的缺点单元格。

(cons 1 (cons 2 (cons 3 nil))) -> (1 2 3)

当我们在列表的末尾插入点时,我们发信号通知读者我们的最终值不是nil而是非空列表。由于非空列表只是一系列缺点,我们基本上都在说:"用这个列表的开头继续cons细胞链。 (在我们的示例中,此非空列表为test,其值为(a test)

如果我们的列表没有以nil结尾,那么读者将始终以点显示这一事实:

(cons 1 (cons 2 3)              -> (1 2 . 3)
相关问题