[plt-scheme] define-literal-set errors
Eli Barzilay wrote:
> On Sep 25, Neil Toronto wrote:
>> Version 4.2.1.8-svn14sep2009
>>
>> First error:
>>
>> (require (for-syntax syntax/parse))
>> (define-literal-set bars (bar))
>> ; expand: unbound identifier in module in: define-literal-set
>>
>> Fix:
>>
>> (require syntax/parse)
>> (define-literal-set bars (bar))
>>
>> But I have to (require (for-syntax syntax/parse)) because I'm using it
>> within define-syntax. Is it typical to have to require a module
>> for-syntax and not for-syntax?
>
> IME, this happens very rarely because the kind of functionality that
> you need on each level is very different. (I've had some cases where
> I needed things like `scheme/list' or `scheme/path' in both, but not
> much more than that.)
>
> Specifically in this case, when you say "... because I'm using it
> within `define-syntax'" the first thing I'm thinking is that you're
> doing something wrong, and that not-for-syntax require is not going to
> help you[*].
>
>
>> Second error:
>>
>> (require syntax/parse
>> (for-syntax syntax/parse))
>>
>> (define-literal-set bars (bar))
>>
>> (syntax-parse #'bar #:literal-sets (bars)
>> [bar #'0]
>> [x #'1])
>> ; = #'0
>>
>> (define-syntax (foo stx)
>> (syntax-parse stx #:literal-sets (bars)
>> [(_ bar) #'0]
>> [(_ x) #'1]))
>> ; syntax-parse: expected identifier defined as a literal-set in: bars
>>
>> If I comment out the definition of (foo stx), the macro stepper says
>> that "bars" is unbound in the transformer phase. I'm fairly sure
>> this is not my error. In the meantime, is there a way to copy the
>> definition of "bars" into the transformer phase?
>
> I wouldn't be surprised at that -- `bars' is something that you need
> at the syntax phase, so you need to use it there instead of at the
> runtime. As far as copying definitions from one phase to another --
> that's an even stronger sign that you're doing things wrong.
>
> Just based on how it looks like (because I have nearly zero experience
> with `syntax/parse'), I think that this is what you want:
>
> #lang scheme
> (require (for-syntax syntax/parse))
> (begin-for-syntax
> (define-literal-set bars (bar)))
> (define-syntax (foo stx) ...)
>
> But this doesn't work because of the limitation that Matthias referred
> to in his reply -- you can't use macros in a `begin-for-syntax'. An
> easy way around that in this case (which seems to work) is:
>
> #lang scheme
> (require (for-syntax syntax/parse))
> (define-syntax foo
> (let ()
> (define-literal-set bars (bar))
> (lambda (stx)
> (syntax-parse stx #:literal-sets (bars)
> [(_ bar) #'0]
> [(_ x) #'1]))))
>
> If you have several macros that need that `bars' definition, then you
> can use `define-syntaxes' to have them all in a single expression.
>
> If you have enough code that makes this too verbose and/or
> inconvenient, then you can switch the whole code down to the runtime,
> and have a separate module that uses all of that at syntax-time -- and
> that's when you need to require `syntax/parse' normally and *not* for
> syntax (which is where [*] is needed). The slightly tricky thing is
> to remember to require scheme `for-template', because everything has
> shifted down.
>
> #lang scheme
> (require syntax/parse (for-template scheme))
> (define-literal-set bars (bar))
> (provide foo)
> (define (foo stx)
> (syntax-parse stx #:literal-sets (bars)
> [(_ bar) #'0]
> [(_ x) #'1]))
>
> And now use it as:
>
> #lang scheme
> (require (prefix-in * (for-syntax "x")))
> (define-syntax foo *foo)
>
That... was really long and helpful. Thanks!
Neil