Синтаксические правила схемы - Разница в привязках переменных между (let) и (define) - PullRequest
2 голосов
/ 03 ноября 2011

Спецификация R 5 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)

У кого-нибудь есть понимание того, что здесь происходит? Что должно произойти за R 5 RS?

1 Ответ

4 голосов
/ 03 ноября 2011

Это обычный трюк, которым пользуются схемы при работе с переопределениями в REPL - рассматривая их как мутацию для существующей привязки. Таким образом, вторая define на самом деле не создает новую привязку, а вместо этого просто set! представляет существующую.

...