[plt-scheme] identifier-binding question
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
>