[racket] Internal definition contexts for phase 1?

From: J. Ian Johnson (ianj at ccs.neu.edu)
Date: Tue Oct 16 15:54:50 EDT 2012

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))

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?

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))
> (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
> (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))))))

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?


Posted on the users mailing list.