Ответ 1
В простой схеме R5RS нет модульной системы - только для верхнего уровня. Кроме того, менталитет состоит в том, что все может быть изменено, поэтому вы можете "настроить" язык любым способом. Но без модульной системы это не работает. Например, я пишу
(define (sub1 x) (- x 1))
в библиотеке, которую вы загружаете, и теперь вы можете переопределить -
:
(define - +) ; either this
(set! - +) ; or this
и теперь вы случайно отключили мою библиотеку, которая полагалась на sub1
, декрементируя ее ввод одним, и в результате ваши окна поднимаются, когда вы перетаскиваете их или что-то еще.
Единственный путь, который используется несколькими библиотеками, - это "захватить" соответствующее определение функции вычитания, прежде чем кто-то сможет его изменить:
(define sub1 (let ((- -)) (lambda (x) (- x 1))))
Теперь все будет работать "более хорошо", так как вы не можете изменить значение моей функции sub1
, изменив -
. (За исключением... если вы измените его, прежде чем загружать мою библиотеку...)
В любом случае, в результате этого (и если вы знаете, что -
является исходным при загрузке библиотеки), некоторые компиляторы обнаружат это и видят, что вызов -
всегда будет фактическая функция вычитания и, следовательно, они будут входить в нее (и включение вызова -
может в конечном итоге привести к сборочному коду для вычитания двух чисел, так что это большой ускорение скорости). Но, как я сказал в приведенном выше комментарии, это более похоже на фактическую причину выше.
Наконец, R6RS (и несколько реализаций схемы до этого) исправил это и добавил библиотечную систему, поэтому нет смысла использовать этот трюк: код sub1
безопасен, если другой код в его библиотеке не переопределяет -
в некотором роде, и компилятор может безопасно оптимизировать код на основе этого. Нет необходимости в умных трюках.