2010-08-14 9 views
11

Io sono da un background imperativo, ma questi giorni cercando le mani su LISP (LISP comune)uscita imprevisto con cons()

ho letto here circa cons che

(cons x L):

Dato un oggetto x LISP e una lista L, valutando (cons x L) crea un elenco contenente x seguito dagli elementi di L.

Quando intenzionalmente non ho usato una lista come secondo argomento quando ho usato

(cons 'a 'a) Mi aspettavo un errore ma whoa! Ho ottenuto (A . A).

Cosa ho perso e cosa è (A . A)?

risposta

7

Cons costruisce una "cella cons". All'inizio questo non ha niente a che fare con le liste. Una cella di controllo è una coppia di due valori. Una cella contro è rappresentata in forma scritta da una "coppia puntata", ad es. (A . B), che contiene i due valori 'A e 'B.

I due punti in una cella di controllo sono chiamati "auto" e "cdr". È possibile visualizzare una cella quali svantaggi come un blocco Diviso in due parti:

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

In Lisp, un valore può anche essere un riferimento a qualcos'altro, ad esempio, un'altra cella cons:

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

Questo sarebbe rappresentato in forma "doppietta" come (A . (B . C)). È possibile continuare in questo modo:

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

Questo è (A . (B . (C . D))). Come si può vedere, in una struttura di questo tipo, i valori sono sempre nello car di una cella contro e il cdr punta al resto della struttura. Un'eccezione è l'ultimo valore, che si trova nell'ultimo cdr. Tuttavia, non abbiamo bisogno di questa eccezione: esiste un valore speciale NIL in Lisp, che indica "nulla".Mettendo NIL nell'ultimo cdr, si dispone di un valore sentinella a portata di mano, e tutti i i valori sono nei car s:

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

Questo è come una lista è costruito in Lisp. Poiché (A . (B . (C . (D . NIL)))) è un po 'ingombrante, può anche essere rappresentato semplicemente come (A B C D). NIL è anche chiamato la lista vuota (); queste sono notazioni scambiabili per la stessa cosa.

Ora è possibile vedere perché (cons x list) restituisce un altro elenco. Cons costruisce semplicemente un'altra cella cons con x nel car e un riferimento alla list nel cdr:

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

e se list è (A B), funziona come:

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

Quindi, (cons x '(a b)) viene valutato come (x a b).

Le liste sono solo un uso molto comune delle celle contro. Puoi anche costruire alberi arbitrari da cellule cons, o liste circolari, o qualsiasi grafico diretto, in realtà.

1

'a è un atomo lisp e (A . A) è un elenco degenere chiamato cons cell o "coppia puntata". Dal momento che non hai passato una lista per argomento L in (cons x L) hai recuperato una cella.

+1

CONS restituisce sempre una cella. –

1

(CONS x L)

x Given e L, CONTRO restituisce una nuova cella cons con x come la macchina di quella cella e L come CDR di quella cella.

Le liste sono catene collegate di celle contro.

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 

Se CONS ottiene due simboli come un argomento che assomiglia a questo:

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

[*|*]---> BAR 
    | 
    v 
FOO 
Problemi correlati