О каких особых формах Схемы должен знать гигиенический макроэспандер?

syntax-rulesв Scheme являются «гигиеническими» и «ссылочно прозрачными» и должны сохранять лексическую область видимости Scheme. Насколько я понимаю, это означает, что на этапе макрорасширения расширитель должен знать о и.

  • О расширителе нужно знать. Предположим, у нас есть такой код:
            (define x 1)
    ((lambda (x) x) 2)
    
    Если бы расширитель не знал об особой форме, он считал бы две s в (lambda (x) x) быть привязанным к x в (define x 1), что неверно.
  • Экспандеру необходимо знать о define, так что он знает, где (то есть в какой области) определен конкретный идентификатор. Вдобавок предположим, что у нас есть такой код:
            (define n 1)
    (define f (lambda (x y) (+ x y)))
    (define lambda f)
    (lambda n n)
    
    Чтобы правильно определить, что оба n в (lambda n n) Ссылаться на (define n 1), расширитель должен понимать, что (define lambda f) изменил значение lambda (и поэтому расширитель должен отказаться от специальных правил обращения с lmabda в этой области).

О каких еще специальных формах нужно знать макрорасширителю? Нужно ли знать о set!?

1 ответ

Примеры, похоже, касаются лексического охвата, а не расширения макросов.

      (define x 1)
((lambda (x) x) 2)

Привязка x во второй строке затеняет привязку в первой.

Аналогично во втором примере (define lambda f)связывается в области, следующей за определением; расширения макросов нет.

Идентификатор lambda может использоваться как ключевое слово в синтаксическом расширении (макросе); лексическая область видимости применяется обычно, особых правил нет:

      > (let-syntax ([lambda (syntax-rules ()
        [(lambda arg) ((lambda (x) (+ 1 x)) arg)])])
    (lambda 2))
3
>

Но:

      > (letrec-syntax ([lambda (syntax-rules ()
        [(lambda arg) ((lambda (x) (+ 1 x)) arg)])])
    (lambda 2))
Exception: invalid syntax (lambda (x) (+ 1 x))
>
Другие вопросы по тегам