lisp - "Cons"在 Lisp 中如何工作?

标签 lisp common-lisp cons

我正在学习 Lisp,但我没有 Lisp 编程经验。在我的部分研究中,我遇到了以下示例:

> (cons ‘a ‘(a b))  ----> (A A B)
> (cons ‘(a b) ‘a)  ----> ((A B).A)

我想知道为什么当我们有 (cons 'a '(a b)) 时响应是 (A A B) 以及为什么当我们稍微改变它并把'a(a b) 之后,响应是一个虚线列表,如((A B).A)?第一个代码行和第二个代码行有什么区别?这些代码背后发生了什么?

最佳答案

如果你把它们想象成cons-cells就很容易理解了.

简而言之,cons 单元格由正好 两个值组成。通常的表示法是使用点,例如:

(cons 'a 'b) ==> (A . B)

但是由于在 LISP 中经常使用列表,所以更好的表示法是去掉点。 列表是通过让第二个元素成为一个新的 cons 单元格,最后一个结束符作为终止符(通常是 nil,或 Common Lisp 中的 '())来创建的。所以这两个是相等的:

(cons 'a (cons 'b '())) ==> (A B)
(list 'a 'b) ==> (A B)

因此 (cons 'a 'b) 创建了一个单元格 [a,b],而 (list 'a 'b) 将创建 [a, [b, nil]]。请注意 cons 单元格中编码列表的约定:它们以内部 nil 结束。

现在,如果您将 'a 添加到最后一个列表中,您将创建一个包含 [[a, [b, nil]], a] 的新 cons 单元格。因为这不是一个“正确的”列表,即它没有以 nil 结尾,所以写出它的方法是使用点:(cons '(a b) 'a) = => ((a b) . a).

如果没有打印点,则它必须是具有结构 [[a, [b, nil]], [a, nil]] 的列表。

你的例子

当你执行 (cons 'a '(a b)) 时,它将采用符号 'a 和列表 '(a b)并把他们放在一个新的牢房里。所以这将由 [a, [a, [b, nil]]] 组成。因为这自然以内部 nil 结尾,所以它没有点。

至于(cons '(a b) 'a),现在你会得到[[a, [b, nil]], a]。这不会以内部 nil 终止,因此将使用点符号。

我们可以使用 cons 使最后一个示例以内部 nil 结尾吗?是的,如果我们这样做

(cons '(a b) (cons 'a '())) ==> ((A B) A)

最后,

(list '(a b) 'a))

相当于

(cons (cons (cons 'a (cons 'b '())) (cons 'a '())))

关于lisp - "Cons"在 Lisp 中如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29703516/

相关文章:

clojure - 用 Clojure 重写 Land of Lisp Wizard 游戏

scheme - (define (add x y) (+ x y)) 和 (define add (lambda (x y) (+ x y))) 有什么区别?

lisp - 如何创建对应于 C 宏的 Lisp FLI 函数

scheme - SICP 练习 2.04

file-io - 为什么 line-seq 返回 clojure.lang.Cons 而不是 clojure.lang.LazySeq?

list - 方案:当我使用两个原子时,我在中间得到一个点。为什么?

lisp - 复杂循环优化

lisp - 为什么 null 谓词称为 null,而不是 nullp?

open-source - 寻找迷你语言的 (c)lisp 示例,即 DSL

lisp - Lisp 中的相等和反向函数