Процедура против макроса в среде верхнего уровня - PullRequest
1 голос
/ 20 апреля 2011

Буду признателен за помощь в понимании различий в поведении между процедурой и макросом в описанных ниже случаях.

Ситуация 1 (процедура)

(define bar (lambda (x) (foo x))) ; closure of 'bar' contains top-level...
; ... environment where 'foo' is not bound yet
;
(define foo (lambda (x) (* x 4))) ; now, 'foo' is bound in top-level environment
;
(bar 2) ; ==> 8 ; when this line is evaluated, 'foo' is available in ...
; ... the top-level environment, so in the closure of 'bar'

Мне это кажется правильным.

Ситуация 2 (макрос)

Давайте попробуем использовать макрос вместо процедуры во 2-й строке:

(define bar (lambda (x) (foo x))) ; closure of 'bar' contains...
; ... top-level environment where 'foo' is not bound yet
;
(define-syntax foo
  (syntax-rules ()
    ((foo arg1) (* 4 arg1)))) ; I thought that 'foo' was bound in...
; ... top-level environment to the macro
;
(bar 2) ; ==> ERROR: reference to undefined identifier: foo

Я не понимаю ошибки.Почему привязка "foo <-> macro" не видна, когда (полоса 2) вычисляется, тогда как она находится в среде верхнего уровня, то есть в закрытии 'bar'?

Перестановка 1-й и 2-й строки решает проблему, но я не понимаю, почему:

(define-syntax foo
  (syntax-rules ()
    ((foo arg1) (* 4 arg1)))) 
;
(define bar (lambda (x) (foo x))) 
;
(bar 2) ; ==> 8

Заранее спасибо за вашу помощь!: -)

С уважением,

Николас

1 Ответ

1 голос
/ 20 апреля 2011

В рабочей версии, поскольку макрос уже определен, система развернет макрос, поэтому вы получите:

(define bar (lambda (x) (* 4 x)))

Однако в нерабочей версии макрос еще не определен и не расширяется. Во время выполнения функция bar ожидает найти процедуру foo, которая не существует.

...