Хорошо, это довольно простой вопрос: я следую за SICP-видео, и я немного смущен различиями между define
, let
и set!
.
1) Согласно Суссману в видео, define
разрешено присоединять значение к avariable только один раз (кроме случаев, когда в REPL), в частности два разрешенных в строке не допускаются. Тем не менее, Guile успешно запускает этот код
(define a 1)
(define a 2)
(write a)
и выводит 2, как и ожидалось. Это немного сложнее, потому что если я попытаюсь сделать это (EDIT: после указанных выше определений)
(define a (1+ a))
Я получаю сообщение об ошибке, а
(set! a (1+ a))
разрешено. Тем не менее, я не думаю, что это единственное различие между set!
и define
: чего я не хватает?
2) Разница между define
и let
еще более заводит меня в голову. Я знаю теоретически let
используется для привязки переменных в локальной области. Тем не менее, мне кажется, что это работает с define
, например, я могу заменить
(define (f x)
(let ((a 1))
(+ a x)))
с
(define (g x)
(define a 1)
(+ a x))
и f
и g
работают одинаково: в частности переменная a
также несвязана вне g
.
Единственный способ, который я вижу в этом полезном, - это то, что let
может иметь более короткую область видимости всей функции. Тем не менее мне кажется, что всегда можно добавить анонимную функцию для создания необходимой области и сразу вызвать ее, как и в javascript. Итак, каково реальное преимущество let
?