Хорошо, это довольно простой вопрос: я следую за 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?