uscita imprevisto con cons ()
-
28-09-2019 - |
Domanda
Sono da un background imperativo ma in questi giorni cercando le mani su LISP (LISP comune)
qui su cons
che
(cons x L):
Dato un oggetto x LISP e una lista L, valutando (cons x L) crea un elenco contenente x seguite da elementi a L.
Quando ho volutamente non ho usato una lista come la seconda cioè argomento quando ho usato
(cons 'a 'a)
mi aspettavo un errore, ma Whoa! Ho (A . A)
.
Quello che ho ho perso e che cosa è (A . A)
?
Soluzione
Cons
costruisce una "cella cons". Questo non ha nulla a che fare con le liste in un primo momento. Una cella cons è una coppia di due valori. Una cella cons è rappresentato in forma scritta da un "coppia tratteggiata", ad esempio (A . B)
, che detiene i due valori 'A
e 'B
.
I due posti in una cella cons sono chiamati "auto" e "cdr". È possibile visualizzare tale cellula contro un 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 "pair punteggiata" come (A . (B . C))
. È possibile continuare in questo modo:
+-----+-----+ +-----+-----+ +-----+-----+
| A | --------> | B | --------> | C | D |
+-----+-----+ +-----+-----+ +-----+-----+
Questa è (A . (B . (C . D)))
. Come si può vedere, in una tale struttura, i valori sono sempre in car
di una cellula contro, ei punti cdr
al resto della struttura. Un'eccezione è l'ultimo valore, che è in ultima cdr
. Non abbiamo bisogno di questa eccezione, però: c'è uno speciale NIL
valore in Lisp, che denota "niente". Mettendo NIL
nell'ultimo cdr
, si dispone di un valore sentinella a portata di mano, e tutti i valori sono in car
s:
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
| A | --------> | B | --------> | C | --------> | D | NIL |
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
Questo è come una lista è costruito in Lisp. Poiché (A . (B . (C . (D . NIL))))
è un ingombrante bit, può anche essere rappresentato semplicemente come (A B C D)
. NIL
è chiamato anche l'elenco ()
vuoto; questi sono notazioni exchangable per la stessa cosa.
Ora si può vedere perché (cons x list)
ritorna un'altra lista. Cons
costruisce semplicemente un'altra cella cons con x
nel car
e un riferimento list
nella cdr
:
+-----+-----+
| X | --------> list
+-----+-----+
e se list
è (A B)
, funziona come:
+-----+-----+ +-----+-----+ +-----+-----+
| X | --------> | A | --------> | B | NIL |
+-----+-----+ +-----+-----+ +-----+-----+
Quindi, valuta (cons x '(a b))
a (x a b)
.
Le liste sono solo un uso molto comune di celle cons. È anche possibile costruire alberi arbitrari da cellule cons o liste circolari o qualsiasi grafo orientato, in realtà.
Altri suggerimenti
'a
è un atomo di LISP e (A . A)
è una lista degenerato chiamato contro cellule o " pair tratteggiata". Dal momento che non avete superato una lista per argomenti L
in (cons x L)
sei tornato una cella.
(CONS x L)
x e L dato, CONS restituisce una nuova cella cons con x come la macchina di quella cella e L come il CDR di quella cella.
Le liste sono collegate catene di cellule cons.
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 appare così:
CL-USER 143 > (sdraw (cons 'foo 'bar))
[*|*]---> BAR
|
v
FOO