2010-08-14 5 views
11

Je suis d'un fond impératif, mais ces jours-ci en essayant mes mains sur LISP (Common Lisp)sortie inattendue avec le contre()

J'ai lu here à propos cons que

(contre x L):

Étant donné un objet de LISP x et une liste L, l'évaluation (cons x L) crée une liste contenant x suivie par les éléments de L.

Quand je intentionnellement n'a pas utilisé une liste comme deuxième argument i.e quand j'ai utilisé

(cons 'a 'a) Je m'attendais à une erreur mais whoa! J'ai eu (A . A).

Qu'est-ce que j'ai manqué et qu'est-ce que (A . A)?

Répondre

7

Cons construit une "cellule de contre". Cela n'a rien à voir avec les listes au début. Une cellule cons est une paire de deux valeurs. Une cellule cons est représentée sous forme écrite par une "paire pointée", par ex. (A . B), qui contient les deux valeurs 'A et 'B.

Les deux emplacements d'une cellule de contre-exemple sont appelés "car" et "cdr". Vous pouvez visualiser une telle cellule contre un bloc coupé en deux:

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

En Lisp, une valeur peut aussi être une référence à quelque chose d'autre, par exemple, une autre cellule de contre:

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

Ce serait représenté sous forme de "paire pointée" sous la forme (A . (B . C)). Vous pouvez continuer comme ça:

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

C'est (A . (B . (C . D))). Comme vous pouvez le voir, dans une telle structure, les valeurs sont toujours dans la car d'une cellule par défaut, et les cdr pointent vers le reste de la structure. Une exception est la dernière valeur, qui est dans la dernière cdr. Nous n'avons pas besoin de cette exception, cependant: il y a une valeur spéciale NIL dans Lisp, qui indique "rien".En mettant NIL dans le dernier cdr, vous avez une valeur sentinelle à portée de main, et tous vos valeurs sont dans les car s:

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

Voici comment une liste est construite en Lisp. Depuis (A . (B . (C . (D . NIL)))) est un peu lourd, il peut également être représenté simplement comme (A B C D). NIL est également appelée la liste vide (); ce sont des notations échangeables pour la même chose.

Maintenant vous pouvez voir pourquoi (cons x list) retourne une autre liste. Cons construit simplement une autre cellule de contre avec x dans le car et une référence à list dans le cdr:

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

et si list est (A B), cela fonctionne comme:

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

Ainsi, (cons x '(a b)) évalue à (x a b).

Les listes sont juste une utilisation très commune de contre les cellules. Vous pouvez également construire des arborescences arbitraires à partir de cellules ou de listes circulaires, ou de n'importe quel graphe orienté.

1

'a est un atome de lisp et (A . A) est une liste dégénérée appelée cons cell ou "paire pointée". Puisque vous n'avez pas passé une liste pour l'argument L dans (cons x L) vous avez récupéré une cellule.

+1

CONS revient toujours une cellule. –

1

(CONS x L)

Étant donné x et L, CONS retourne une nouvelle cellule cons avec x comme la voiture de cette cellule et de L en tant que CDR de cette cellule.

Les listes sont des chaînes liées de contre-cellules.

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 

Si CONS obtient deux symboles comme argument, elle ressemble à ceci:

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

[*|*]---> BAR 
    | 
    v 
FOO 
Questions connexes