[plt-scheme] Where is macroexpand in PLT Scheme?

From: Richard C. Cobbe (cobbe at ccs.neu.edu)
Date: Wed Nov 12 14:38:12 EST 2003

Lo, on Wednesday, November 12, Joe Marshall did write:

>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
> Bill Clementson <bill_clementson at yahoo.com> writes:
> > --- Joe Marshall <jrm at ccs.neu.edu> wrote:
> >> 
> >> `macroexpand' would only be useful as a top-level
> >> debugging tool.  It
> >> would be quite difficult to make it work `correctly'
> >> with R5RS macros.
> >> I'm guessing that is one reason it is not in R5RS.
> >
> > Very interesting comment. Could you elaborate on this
> > please - how is expanding an R5RS macro different from
> > expanding a CL macro and why is it difficult to make
> > it work "correctly" with R5RS macros? 
> The problem is hygiene.  Free variables in the macro are supposed to
> be bound to the lexical value apparent *at the macro*.
> (define-syntax foo
>   (syntax-rules ()
>     ((foo x) (begin (display "Hello") x))))
> (-test (let ((display 33)) (foo display)))
> (-test :expand)
> --> (let-values (((display) (#%datum . 12))) (#%app (#%top . display) (#%datum . "hi")) display)

Joe is correct, but this phenomenon is typically called "referential
transparency;" hygiene is something different.  Briefly, hygiene is what
makes the following work right:

(define-syntax or
  (syntax-rules ()
    ((or a b) (let ((t a)) (if t t b)))))

(let ((t #f))
  (or 3 t))
;; evaluates to 3

The basic idea: since the macro introduces a new binding for t, where
the name t was not supplied by the user, this binding is supposed to be
kept separate from any bindings that may be in scope at the invocation
of the macro.


Posted on the users mailing list.