我正在学习 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/