'boo
est une abréviation pour (quote boo)
. Dans le code, quote
est une forme spéciale qui évalue à quel que soit son argument et rien de plus. Ainsi, boo
. Lorsque cette valeur est transmise autour de ses données et non plus le code, mais afin de créer le symbole foo
vous avez besoin de quote
.
'''boo
est l'abréviation de (quote (quote (quote boo)))
. En l'évaluant il fait exactement comme avant et il devient (quote (quote boo))
, une liste avec deux éléments où le deuxième élément est une liste de deux éléments.
Puisque eval
est une fonction, il évalue d'abord l'argument, puis il évalue le résultat comme la fonction est supposée le faire. Ainsi (quote (quote foo))
devient (quote foo)
après la première évaluation et eval
enlève la seconde en laissant le symbole foo
.
Si eval
obtient un symbole foo
, cela signifie qu'il est censé obtenir la valeur liée par la variable foo
dans l'espace de noms global. Ainsi:
(defparameter *test* 5)
(eval '*test*)
; ==> 5
Depuis l'argument est (quote *test*)
qui, après évaluation devient *test*
.eval
voit le symbole et récupère la valeur, 5
, qui est le résultat. Si *test*
n'est pas lié, vous obtenez l'erreur que vous avez.
(defparameter *test-symbol* '*test)
(eval *test-symbol*)
Même ici. Puisque c'est une fonction *test-symbol*
est évaluée au symbole *test*
, c'est ce que eval
voit et il récupère la valeur 5
.
(defparameter *result* (eval '''foo))
*result*
; ==> (quote foo) but often the REPL shows 'foo
(consp *result*)
; ==> t
(length *result*)
; ==> 2
(car *result*)
; ==> quote
(cadr *result*)
; ==> foo
Parfois, je vois des débutants faire quelque chose comme '('(a) '(b))
. C'est une erreur car quand vous êtes évalué vous finissez avec la liste ((quote (a)) (quote (b)))
comme les données et c'est rarement l'intention. Lorsque vous utilisez une fonction comme list
les arguments évalués et obtient vous devez citer correctement:
(list '(a) *result* '(b))
; ==> ((a) (quote foo) (b))