What Scheme special forms must the hygienic macro expander know about?

80 Views Asked by At

syntax-rules in Scheme are "hygienic" and "referentially transparent" and must preserve Scheme's lexical scoping. From my understanding, this means that during the macro expansion phase, the expander would need to know about lambda and define.

  • The expander needs to know about lambda. Suppose we have this code:
    (define x 1)
    ((lambda (x) x) 2)
    
    If the expander did not know about the lambda special form, it would consider the two xs in (lambda (x) x) to be bound to the x in (define x 1), which is incorrect.
  • The expander needs to know about define, so that it knows where (i.e. in which scope) a particular identifier is defined. In addition, suppose we have this code:
    (define n 1)
    (define f (lambda (x y) (+ x y)))
    (define lambda f)
    (lambda n n)
    
    In order to correctly determine that both n in (lambda n n) refer to (define n 1), the expander has to understand that (define lambda f) has changed the meaning of lambda (and therefore the expander has to stop using special rules for handling lmabda in this scope).

What other special forms does the macro expander need to know about? Does it need to know about set!?

1

There are 1 best solutions below

0
On

The examples seem to be about lexical scoping, not macro expansion.

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

The binding of x in the second line shadows that in the first.

Similarly in the second example (define lambda f) binds lambda in the region following the define; there is no macro expansion.

The identifier lambda can be used as a keyword in a syntactic extension (macro); lexical scoping applies normally, there are no special rules:

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

But:

> (letrec-syntax ([lambda (syntax-rules ()
        [(lambda arg) ((lambda (x) (+ 1 x)) arg)])])
    (lambda 2))
Exception: invalid syntax (lambda (x) (+ 1 x))
>