Bien que tous les deux define
et set!
redéfinir une valeur lorsque dans la même portée, ils font deux choses différentes lorsque la portée est différente. Voici un exemple:
(define x 3)
(define (foo)
(define x 4)
x)
(define (bar)
(set! x 4)
x)
(foo) ; returns 4
x ; still 3
(bar) ; returns 4
x ; is now 4
Comme vous pouvez le voir, lorsque nous créons un nouveau champ lexical (par exemple lorsque nous define
une fonction), les noms définis dans ce champ masquer les noms qui apparaissent dans la portée englobante. Cela signifie que lorsque nous define
d x
à 4
dans foo
, nous avons vraiment créé une nouvelle valeur pour x
qui ombragé l'ancienne valeur. Dans bar
, puisque foo
n'existe pas dans cette portée, set!
recherche dans la portée englobante pour rechercher et modifier la valeur de x
.
Aussi, comme d'autres personnes l'ont dit, vous êtes seulement supposé define
un nom une fois dans une portée. Certaines implémentations vous permettront de sortir avec plusieurs define
, et d'autres non. En outre, vous êtes seulement supposé utiliser set!
sur une variable qui a déjà été define
d. Encore une fois, la stricte application de cette règle dépend de la mise en œuvre.
Comment concevez-vous un compteur de boucles dans Scheme? –