Chociaż zarówno define
, jak i set!
przedefiniują wartość w tym samym zakresie, robią dwie różne rzeczy, gdy zasięg jest inny. Oto przykład:
(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
Jak widać, gdy tworzymy nowy zakres leksykalny (takich jak, kiedy define
funkcją), wszelkie nazwy zdefiniowane w tym zakresie maskować nazwiska, które pojawiają się w zakresie obejmującym. Oznacza to, że po define
d x
do 4
w foo
, naprawdę stworzyliśmy nową wartość dla x
, która zacieniała starą wartość. W bar
, ponieważ foo
nie istnieje w tym zakresie, set!
szuka zasięgu obejmującego, aby znaleźć i zmienić wartość x
.
Ponadto, jak powiedzieli inni, masz tylko jedną nazwę w zasięgu. Niektóre implementacje pozwolą uciec z wieloma wersjami define
s, a niektóre nie. Ponadto, należy używać tylko set!
dla zmiennej, która już była define
d. Ponownie, jak ściśle ta zasada jest egzekwowana, zależy od implementacji.
Jak zaprojektowałbyś licznik pętli w Scheme? –