Aunque tanto define
como set!
redefinirán un valor cuando están en el mismo ámbito, hacen dos cosas diferentes cuando el alcance es diferente. He aquí un ejemplo:
(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
Como se puede ver, cuando creamos un nuevo ámbito léxico (por ejemplo, cuando nos define
una función), los nombres definidos dentro de ese ámbito enmascarar los nombres que aparecen en el ámbito de inclusión. Esto significa que cuando define
d x
a 4
en foo
, realmente creamos un nuevo valor para x
que sombreaba el valor anterior. En bar
, dado que foo
no existe en ese ámbito, set!
busca en el alcance adjunto para buscar y cambiar el valor de x
.
Además, como han dicho otras personas, se supone que solo define
un nombre en el ámbito. Algunas implementaciones le permitirán salirse con múltiples define
s, y otras no. Además, solo debe usar set!
en una variable que ya ha sido define
d. De nuevo, cuán estrictamente se aplica esta regla depende de la implementación.
¿Cómo diseñaría un contador de bucles en Scheme? –