В Схеме цель (позволяют ((CDR CDR))

Я изучал Схему недавно и сталкивался с функцией, которая определяется следующим образом:

(define remove! 
    (let ((null? null?)
          (cdr cdr)
          (eq? eq?))
     (lambda ... function that uses null?, cdr, eq? ...)

Что цель связать является пустым? к пустому указателю? или CDR к CDR, когда они создаются в функциях, которые доступны в функциональном определении без блока, которому позволяют?

14
задан redwoolf 9 July 2010 в 14:37
поделиться

2 ответа

В простой R5RS Scheme нет системы модулей - только верхний уровень. Более того, менталитет таков, что все может быть изменено, так что вы можете "настраивать" язык как угодно. Но без системы модулей это работает плохо. Например, я пишу

(define (sub1 x) (- x 1))

в библиотеке, которую вы загружаете - и теперь вы можете переопределить -:

(define - +) ; either this
(set! - +)   ; or this

и теперь вы непреднамеренно сломали мою библиотеку, которая полагалась на sub1, уменьшающую свой вход на единицу, и в результате ваши окна поднимаются, когда вы перетаскиваете их вниз, или что угодно.

Единственный способ обойти это, который используется несколькими библиотеками, - "захватить" соответствующее определение функции вычитания, прежде чем кто-то сможет его изменить:

(define sub1 (let ((- -)) (lambda (x) (- x 1))))

Теперь все будет работать "более тонко", поскольку вы не сможете изменить значение моей функции sub1, изменив -. (За исключением... если вы измените ее до загрузки моей библиотеки... )

В любом случае, в результате этого (и если вы знаете, что - является оригиналом при загрузке библиотеки), некоторые компиляторы обнаружат это и увидят, что вызов - всегда будет фактической функцией вычитания, и поэтому они будут инлайнить вызовы к ней (а инлайнинг вызова - может в конечном итоге привести к ассемблерному коду для вычитания двух чисел, так что это большой прирост скорости). Но, как я уже сказал в комментарии выше, это больше совпадает с фактической причиной, указанной выше.

Наконец, в R6RS (и нескольких реализациях схемы до этого) это исправлено и добавлена библиотечная система, так что этот трюк не используется: код sub1 безопасен до тех пор, пока другой код в его библиотеке не переопределяет - каким-либо образом, и компилятор может безопасно оптимизировать код на основе этого. Нет необходимости в хитроумных уловках.

30
ответ дан 1 December 2019 в 08:42
поделиться

Это оптимизация скорости. Доступ к локальным переменным обычно быстрее, чем к глобальным переменным.

2
ответ дан 1 December 2019 в 08:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: