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

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

我不知道为什么,当我们有(利弊“A”(AB))的响应(AAB),为什么当我们改变了一点,把“一个(AB),响应是像 ((AB).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) 并将它们放入新的 cons 单元格中。所以这将由 [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/

10-12 18:50