What's the point of using the set!
assignment operator in scheme? Why not just rebind
a variable to a new value using define
?
> (define x 100)
> (define (value-of-x) x) ;; value-of-x closes over "x"
> x
100
> (value-of-x)
100
> (set! x (+ x 1))
> x
101
> (value-of-x)
101
> (define x (+ x 1))
> x
102
> (value-of-x)
102
>
Though both define
and set!
will redefine a value when in the same scope, they do two different things when the scope is different. Here's an example:
(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
As you can see, when we create a new lexical scope (such as when we define
a function), any names defined within that scope mask the names that appear in the enclosing scope. This means that when we define
d x
to 4
in foo
, we really created a new value for x
that shadowed the old value. In bar
, since foo
does not exist in that scope, set!
looks to the enclosing scope to find, and change, the value of x
.
Also, as other people have said, you're only supposed to define
a name once in a scope. Some implementations will let you get away with multiple define
s, and some won't. Also, you're only supposed to use set!
on a variable that's already been define
d. Again, how strictly this rule is enforced depends on the implementation.