О каких особых формах Схемы должен знать гигиенический макроэспандер?
syntax-rules
в Scheme являются «гигиеническими» и «ссылочно прозрачными» и должны сохранять лексическую область видимости Scheme. Насколько я понимаю, это означает, что на этапе макрорасширения расширитель должен знать о и.
- О расширителе нужно знать. Предположим, у нас есть такой код:
(define x 1) ((lambda (x) x) 2)
(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))
>