缺陷指向相同的其他缺点

时间:2016-07-26 23:24:29

标签: list lisp

我想在Lisp中创建以下列表。

Picture of two cons cells, both cells in the first are pointing to the second, which contains A and B

((lambda(x) (cons x x)) (cons'A 'B))

创建此列表,但

((lambda(x y) (cons x y)) (cons'A 'B) (cons 'A 'B))

(cons (cons 'A 'B) (cons 'A 'B))

不要创建列表。

我的挑战是为什么!?第一个命令如何创建此列表而其他命令没有?任何细节?

2 个答案:

答案 0 :(得分:4)

每次调用(cons 'A 'B)时,都会创建一个fresh缺点单元格,因此您的后两个表达式会创建两个“相似”(equal但不会{ {3}})对象(A . B)

答案 1 :(得分:4)

您想要创建A和B的cons

(cons 'A 'B)

然后你想从另一个缺点中引用它两次。因此,如果x是对现有cons的引用,则需要

(cons x x)

结束,我们得到

(let ((x (cons 'A 'B)) (cons x x))

或等效

((lambda (x) (cons x x)) (cons 'A 'B))

如果您执行(cons 'A 'B)两次,则会创建两个单元格:

  

A

     

A

,其中cons将包含一个指向第一个链接,另一个指向第二个链接。

(使用lambda引用它们是一种毫无意义的混淆;具有lambda形式的示例的是您使用x两次。表格

((lambda (x y) (cons x y)) (cons 'A 'B) (cons 'A 'B))

只是一种非常繁琐的写作方式

(cons (cons 'A 'B) (cons 'A 'B))

而在最初的例子中,只有一个(cons 'A 'B)的实例,你希望能够引用两次。)

本练习的目的是说明“表面”对等与身份之间的区别。包含相同值的两个列表仍然是两个不同的列表,而对同一列表的两个引用是相同的。正如@sde提示的那样,这对理解比较有所帮助;原型示例是equal对于包含相同值的不同列表(当然还有相同的列表)是正确的,而eql仅在其参数实际上相同时才为真(即它们引用到同一个对象)。