[racket] Internal definition contexts for phase 1?

From: Ryan Culpepper (ryan at cs.utah.edu)
Date: Tue Oct 16 17:25:28 EDT 2012

On 10/16/2012 03:54 PM, J. Ian Johnson wrote:
> I'm doing a bit of macrobatics where I'm creating a series of definitions, during which I want to also do define-for-syntax for some syntax transformers that are used in a produced syntax-parameterize form.
>
> In a top level call to this macro, things would be fine. However, I set up some syntax parameters first with splicing-syntax-parameterize.
>
> Now I get an error of the form
>
> begin-for-syntax: not in a definition context
>    in: (begin-for-syntax (define-values (foo) foo-def))
>    context...:
>     backtrace

 From a quick glance at the implementation, this looks like a bug in 
'splicing-syntax-parameterize'. I'll fix it.

> This boils down to the fact that
>
> (let () (define-for-syntax (foo x) x) 0)
>
> is not legal, because the internal definition context set up is only for phase 0.
> How can I get around this? Is this an intended limitation?

Yes. (Ish. For now, anyway.)

> There is more odd behavior to this. Consider the following interaction:
>
> Welcome to Racket v5.3.0.24.
>> (let () (define-syntax foo (λ (stx) (syntax-case stx () [(_ e) #'e]))) (foo 0))
> 0
>> (let ()
>      (define-for-syntax foo-def (λ (stx) (syntax-case stx () [(_ e) #'e])))
>      (define-syntax foo foo-def)
>      (foo 0))
> foo-def: undefined;
>   cannot reference undefined identifier
>    context...:
>     /home/ianj/plt/pltgit/collects/racket/private/misc.rkt:87:7
>> (let () (define-for-syntax foo-def (λ (stx) (syntax-case stx () [(_ e) #'e]))) 0)
> begin-for-syntax: not in a definition context
>    in: (begin-for-syntax (define-values (foo-def) (λ (stx) (syntax-case stx () ((_ e) (syntax e))))))
>    context...:
>     /home/ianj/plt/pltgit/collects/racket/private/misc.rkt:87:7
>
> If the define-for-syntax is just not allowed, then shouldn't I get an error the form of the latter instead of the former?

Yes, although I'm not sure it's possible to reliably detect that 
situation. (I believe that checking syntax-local-context might cause a 
macro to raise an error if it's used within a splicing form, even if the 
splicing form is itself at module level. But I haven't tried it.)

Ryan


Posted on the users mailing list.