Синтаксические правила схемы - Разница в привязках переменных между (let) и (define)
Спецификация R5 RS гласит, что как часть требований для макроса, определенного с использованием syntax-rules
:
Если макротрансформатор вставляет свободную ссылку на идентификатор, ссылка ссылается на привязку, которая была видна там, где был указан преобразователь, независимо от каких-либо локальных привязок, которые могут окружать использование макроса.
Я пытаюсь понять, как это работает на практике. Так, например, если у меня есть следующий код:
(define var 'original)
(define-syntax test-var
(syntax-rules (var)
((_ var)
var)
((_ pattern-var)
'no-match)))
Я ожидаю, что следующее, если выполнено сразу после, оценивать original
, что он делает:
(test-var var)
И я ожидаю, что это будет no-match
так как var
введены в сферу до test-var
не соответствует привязке var
при определении макроса:
(let ((var 1)) (test-var var))
Однако следующий пример меня озадачил:
(define var 'new-var)
(test-var var)
В Куриной Схеме это оценивает к new-var
, Я бы ожидал, что это будет no-match
по тем же причинам, что и предыдущий (let)
пример. Я подумал, что, возможно, это проблема с использованием define
дважды, но результат по-прежнему new-var
даже если я использую (set! var 'new-var)
У кого-нибудь есть понимание того, что здесь происходит? Что должно произойти за R5 RS?
1 ответ
Это обычная хитрость, которую имеют Схемы при работе с переопределениями в REPL - рассматривая их как мутацию для существующей привязки. Итак, второе define
на самом деле не создает новую привязку, а вместо этого просто set!
с существующим.