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