[plt-scheme] identifier-binding question

From: Jos Koot (jos.koot at telefonica.net)
Date: Thu Jan 8 08:55:28 EST 2009

I expected that my question had to do with the order of expansion, but I did 
not think of #%expression as a way to escape too early expansion.
Thanks for your clear answer, it works great.
Jos

----- Original Message ----- 
From: "Matthew Flatt" <mflatt at cs.utah.edu>
To: "Jos Koot" <jos.koot at telefonica.net>
Cc: <plt-scheme at list.cs.brown.edu>
Sent: Thursday, January 08, 2009 2:11 PM
Subject: Re: [plt-scheme] identifier-binding question


> At Thu, 8 Jan 2009 12:26:11 +0100, "Jos Koot" wrote:
>> #lang scheme
>> (define-syntax (x stx)
>>  (syntax-case stx ()
>>   ((_ y)
>>    (let ((x (identifier-binding #'y)))
>>     (cond
>>      ((list? x) #''module)
>>       ((not x) #''top)
>>       ((eq? x 'lexical) #''lexical)
>>       (else #''unexpected))))))
>> (x b) ; --> #f <== I expected `module' ???
>> (define b 3)
>> (x b) ; --> module
>
> This has to do with the order of expansion. Within a module, top-level
> forms are partially expanded in order that they appear. The partial
> expansion goes far enough to determine whether the form is one of
>
>  * `require'
>  * `provide'
>  * `define-syntax'
>  * `define-for-syntax'
>  * `define'
>  * `begin' (body is spliced immediately)
>  * a core expression form
>
> After the macro expander partially expands the module body, then all
> bindings are known and everything left is an expression, and they are
> expanded in a second pass.
>
> So, in the above example, at the point where the first use of `x' is
> being expanded, the `b' definition hasn't been seen, yet.
>
> In practice, when `x' is an expression form, the solution is to expand
> `(x b)' to `(#%expression (real-x b))', and put the real work in the
> `real-x' form. That way, partial expansion of `(x b)' will expose that
> it's an expression form without expanding the part that needs to have
> all bindings available.
>
>
> Matthew
> 



Posted on the users mailing list.