2010-08-14 9 views
11

ich von einem imperativen Hintergrund bin aber in diesen Tagen versuchen, meine Hände auf Lisp (Common Lisp)Unerwartete Ausgabe mit cons()

Ich las here über cons dass

(cons L x):

ein LISP-Objekt x und eine Liste L, Bewertung (cons x L) erstellt eine Liste gegeben x durch die Elemente in L.

Wenn ich absichtlich enthält, gefolgt keine Liste als zweites Argument, d. h. als ich

(cons 'a 'a) Ich habe einen Fehler erwartet, aber whoa! Ich habe (A . A).

Was habe ich vermisst und was ist (A . A)?

Antwort

7

Cons eine "cons Zelle" konstruiert. Dies hat zunächst nichts mit Listen zu tun. Eine Cons-Zelle ist ein Paar von zwei Werten. Eine Cons-Zelle wird in schriftlicher Form durch ein "gepunktetes Paar", z. (A . B), die die beiden Werte 'A und 'B enthält.

Die beiden Orte in einer Cons-Zelle heißen "Auto" und "Cdr". Sie können eine solche Nachteile Zelle als halbierten Block visualisieren:

car cdr 
+-----+-----+ 
| A | B | 
+-----+-----+ 

In Lisp kann ein Wert auch ein Hinweis auf etwas anderes sein, zum Beispiel eine andere Nachteile Zelle:

+-----+-----+  +-----+-----+ 
| A | --------> | B | C | 
+-----+-----+  +-----+-----+ 

Dies wäre in Form eines "gepunktetes Paares" dargestellt als (A . (B . C)). Sie können so weitermachen:

+-----+-----+  +-----+-----+  +-----+-----+ 
| A | --------> | B | --------> | C | D | 
+-----+-----+  +-----+-----+  +-----+-----+ 

Diese (A . (B . (C . D))) ist. Wie Sie sehen können, sind die Werte in einer solchen Struktur immer in der car einer Cons-Zelle, und die cdr zeigt auf den Rest der Struktur. Eine Ausnahme ist der letzte Wert, der in der letzten cdr ist. Wir brauchen diese Ausnahme jedoch nicht: Es gibt einen speziellen Wert NIL in Lisp, der "nichts" bedeutet.Durch NIL in den letzten cdr setzen, haben Sie ein handliches Sentinel-Wert und alle Ihre Werte sind in den car s:

+-----+-----+  +-----+-----+  +-----+-----+  +-----+-----+ 
| A | --------> | B | --------> | C | --------> | D | NIL | 
+-----+-----+  +-----+-----+  +-----+-----+  +-----+-----+ 

Dies ist, wie eine Liste in Lisp aufgebaut ist. Da (A . (B . (C . (D . NIL)))) ein wenig unhandlich ist, kann es auch einfach als (A B C D) dargestellt werden. NIL wird auch die leere Liste () genannt; das sind austauschbare Notationen für dasselbe.

Jetzt können Sie sehen, warum (cons x list) eine andere Liste zurückgibt. Cons einfach konstruiert andere Nachteile Zelle mit x im car und einen Verweis auf list im cdr:

+-----+-----+ 
| X | --------> list 
+-----+-----+ 

und wenn list(A B) ist, klappt es wie:

+-----+-----+  +-----+-----+  +-----+-----+ 
| X | --------> | A | --------> | B | NIL | 
+-----+-----+  +-----+-----+  +-----+-----+ 

So (cons x '(a b)) ausgewertet (x a b).

Listen sind nur eine sehr häufige Verwendung von Cons-Zellen. Sie können auch beliebige Bäume aus Cons-Zellen oder kreisförmigen Listen oder aus beliebigen gerichteten Graphen konstruieren.

1

'a ist ein lisp-Atom und (A . A) ist eine degenerierte Liste namens cons cell oder "gepunktetes Paar". Da Sie keine Liste für das Argument L in (cons x L) übergeben haben, haben Sie eine Zelle zurückbekommen.

+1

CONS gibt immer eine Zelle zurück. –

1

(CONS x L)

gegeben x und L, kehrt CONS eine neue cons Zelle mit x als CAR dieser Zelle und L als die CDR dieser Zelle.

Listen sind verknüpfte Ketten von Cons-Zellen.

CL-USER 141 > (sdraw '(a b c)) 

[*|*]--->[*|*]--->[*|*]---> NIL 
    |  |  | 
    v  v  v 
    A  B  C 

CL-USER 142 > (sdraw (cons 'foo '(a b c))) 

[*|*]--->[*|*]--->[*|*]--->[*|*]---> NIL 
    |  |  |  | 
    v  v  v  v 
FOO  A  B  C 

Wenn CONS zwei Symbole als Argument bekommt sieht es wie folgt aus:

CL-USER 143 > (sdraw (cons 'foo 'bar)) 

[*|*]---> BAR 
    | 
    v 
FOO 
Verwandte Themen