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

È stato utile?

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 cars:

+-----+-----+       +-----+-----+       +-----+-----+       +-----+-----+
|  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
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top