2016-07-26 17 views
2

Ich möchte folgende Liste in Lisp erstellen.Cons Zellen zeigen auf die gleichen anderen Nachteile

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)) 

erstellt diese Liste, aber

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

und

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

Sie die Liste nicht erstellen.

Meine Herausforderung ist warum? Wie erstellt der erste Befehl diese Liste und die anderen nicht? Jedes Detail?

Antwort

4

Jedes Mal (cons 'A 'B) genannt wird, eine fresh cons Zelle erstellt, so dass Ihre zweite beiden Ausdrücke erstellen zwei "ähnlich" (equal aber nicht eql) Objekte (A . B),

+0

Ich lese deine nette Antwort mehr und mehr aber konnte es nicht bekommen. Würden Sie bitte mehr Details hinzufügen? –

+1

Jeder Aufruf von "cons" erzeugt einen neuen. Es ist schwer zu sehen, wie dies verdeutlicht werden könnte. – tripleee

4

Sie möchten eine cons von A erstellen und B:

(cons 'A 'B) 

Dann möchten Sie es zweimal von einem anderen Nachteile beziehen. Also, wenn x ist ein Verweis auf diese bestehende cons, Sie wollen

(cons x x) 

Wrapping up, erhalten wir

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

oder äquivalent

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

Wenn Sie (cons 'A 'B) zweimal tun erstellen Sie zwei Zellen :

AB

AB

und die cons derer wird eine Verbindung zu dem ersten, und einen anderen an den zweiten enthalten.

(ein lambda Mit ihnen beziehen eine sinnlosen Verschleierung ist, der Punkt des Beispiels mit der lambda Form ist, dass Sie x zweimal verwenden Sie das Formular

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

nur ein sehr langwieriger Weg.

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

während im ursprünglichen Beispiel zu schreiben gibt es - pointiert - nur eine Instanz von (cons 'A 'B), die Sie zweimal beziehen können.)

Der Zweck dieser Übung ist es, den Unterschied zwischen "Oberfläche" Äquivalenz und Identität zu veranschaulichen. Zwei Listen, die die gleichen Werte enthalten, sind immer noch zwei verschiedene Listen, während zwei Referenzen auf die gleiche Liste identisch sind. Wie @sde anmerkt, macht dies einen Unterschied für das Verständnis von Vergleichen; Das prototypische Beispiel ist, dass equal für verschiedene Listen gilt, die die gleichen Werte enthalten (natürlich auch identische Listen), wohingegen eql nur wahr ist, wenn seine Argumente tatsächlich identisch sind (d. h. sie beziehen sich auf dasselbe Objekt).

+0

Verrückte Formatierung von http://meta.stackexchange.com/a/128302/169312 – tripleee