В спецификации R5RS указано, что в рамках требований к макросу, определенному с помощью 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)
В Chicken Scheme это оценивается как new-var
. Я ожидал, что это будет no-match
по тем же причинам, что и в предыдущем примере (let)
. Я подумал, что, возможно, это проблема с двойным использованием define
, но результат все равно new-var
, даже если я использую (set! var 'new-var)
Есть ли у кого-нибудь понимание того, что здесь происходит? Что должно произойти за R5RS?