[plt-scheme] expansion of internal define v. set!

From: John Clements (clements at brinckerhoff.org)
Date: Tue Nov 11 10:22:40 EST 2003

On Tuesday, November 11, 2003, at 12:14  AM, David Van Horn wrote:

>   For list-related administrative tasks:
>   http://list.cs.brown.edu/mailman/listinfo/plt-scheme
>
> (define-syntax f
>   (syntax-rules ()
>     ((f e) (define e 'by-syntax))))
>
> (define-syntax f
>   (syntax-rules ()
>     ((f e) (set! e 'by-syntax))))
>
> (let ((x 'undefined))
>   (define (f _) (set! x 'by-procedure))
>   (f x)
>   x)
>
> Using the first syntax definition of f results in 'by-syntax, but 
> using the
> second results in 'by-procedure.  I'm not sure what the right behavior 
> is, but
> it seems like either 'by-syntax or 'by-procedure should be returned in 
> both
> cases.  Is this a bug or am I missing some subtlety in macros that 
> expand into
> definitions?  (I tried this in a module and observed the same 
> behavior.)
>
> (The other Schemes I have lying around, MIT and 48, return 
> 'by-procedure in
> both cases.)

That's a good one!

The behavior of MzScheme is consistent with the following expansion 
discipline:

When expanding the body of a lambda, we need to see whether there are 
internal defines.  To discover this, we need to expand only those 
expressions which turn into 'define's.

So, in the first case, when f expands to a define, MzScheme sees that 
it expands into a define, and therefore parses the body as two internal 
defines followed by a reference to x.

In the second case, f does _not_ expand to a define.  MsScheme 
therefore parses the body as an internal define followed by two 
expressions.  Since the lexical binding of f shadows the macro binding 
of f inside those body expressions, the f becomes a straightforward 
application.

Macros are weird.

john



Posted on the users mailing list.