[plt-scheme] Can generated lexical (syntax) bindings work?

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Apr 7 21:40:12 EDT 2007

I recommend:

 1. Have `define-syntax-in-context' bind a fresh name to the
    transformer using `define-syntax', and also add a mapping in the
    table from the context name and definition symbol to a syntax
    object for the fresh name.

    Do not have the `define-syntax-in-context' macro perform the table
    registration directly. Instead, have it expand to
    `begin-for-syntax' to perform the registration.

 2. Have `with-context' expand to a `let-syntax' that uses
    `make-rename-transformer' to map the defined name to the fresh name
    generated by `define-syntax-in-context'.

    To generate the identifier bound by `let-syntax', use
    `datum->syntax-object' with the context identifier supplied to
    `with-context' and the symbol for the defined name.

Using `make-rename-transformer' is the key part of this strategy. It
only works when the context for a use is nested within the context for
a definition (where all module top levels count as the same top level
for this notion of "nesting"); my guess is that's fine for your
purposes.

If it doesn't work out, post the code for your attempt, and we can help
more from there.

Matthew

At Fri, 6 Apr 2007 13:27:22 -0700, Brian Chin wrote:
> Hey all, I have a bit of a long problem (with a possibly shorter  
> answer). I'm trying to write a small module which allows you to  
> define a syntax definition in a separate context, so that it isn't  
> actually defined at the top level. Later when you want to use it, you  
> can declare that some syntax be run in that context, thus enabling  
> those syntax bindings. A quick example:
> 
> (define-syntax-in-context foo my-context
>    (syntax-rules () ((foo) 5)))
> 
> (foo) ; Syntax error, foo is not defined
> 
> (with-context my-context (foo)) ; Equivalent to just 5
> 
> Now, the problem I'm having is in saving the symbol foo from the  
> define-syntax-in-context call to actually bind to the "foo" in the  
> with-context call. Most of the approaches I've tried hasn't allowed  
> with-context to generate a new lexical binding for "foo". This is  
> definitely non-hygienic, but it seems like it should still be  
> possible. I've tried three things, all of which save information  
> about mappings from (context, syntax-name) -> transformer in one  
> fashion or another:
> 
> 1. define-syntax-in-context saves the transformer syntax object in a  
> hash table keyed by the context symbol and the syntax name symbol,  
> both extracted using syntax-object->datum. With-context generates a  
> let-syntax form, and generates new syntax objects for the syntax-name  
> using datum->syntax-object. This doesn't seem to work, as (foo) is  
> still being interpreted as a top-level form.
> 
> The code it's generating is something like this:
> 
> (let-syntax ((foo (syntax-rules () ((foo) 5)))) (foo))
> 
> But it's still failing.
> 
> 2. define-syntax-in-context effectively executes the transformer  
> expression, creating the actual transformer function. It also  
> declares a top-level macro with the same name. When that macro is  
> called, it looks up the current context from a global variable with  
> dynamic scope, and then applies the appropriate transformer. This  
> works, but since this requires a top-level syntax declaration and  
> uses dynamic scope, I find this solution unsatisfying.
> 
> 3. Similar to the original, I save the transformer syntax objects in  
> a hash table. Instead of making let-syntax terms, I create a syntax  
> environment using syntax-local-make-definition-context and syntax- 
> local-bind-syntaxes, and apply it to the body using local-expand, and  
> return the result. This seems to work part of the time, as long as  
> the with-context is being called in the module where the syntax was  
> originally declared. However, it fails at weird times. For instance,  
> in this same macro, I made another syntax object which uses with- 
> context to process one set of syntax multiple times in different  
> contexts. That doesn't seem to work.
> 
> It seems that one of my troubles relates to the actual generated  
> symbol syntax-object made from datum->syntax-object, possibly related  
> to the context syntax object I have to pass. Am I making some sort of  
> silly mistake, or is there something wrong with the way I'm  
> approaching this problem?
> 
> Thanks in advance,
> - Brian Chin



Posted on the users mailing list.