[plt-scheme] Evaling syntax with module bindings

From: Lauri Alanko (la at iki.fi)
Date: Sun Jan 29 17:00:13 EST 2006

I need syntax objects that refer to a variable in a particular module.
This is how it works normally:

> (module a mzscheme (provide xa) (define xa 42))
> (module b mzscheme
(require-for-template mzscheme a) (provide xb) (define xb #'xa))
> (require-for-syntax b)
> (define-syntax (foo stx) xb)
> (foo)
reference to an identifier before its definition: xa in module: a

 === context ===
loop
read-eval-print-loop

> (require a)
> (foo)
42

I'm not quite sure why there is an error unless I (require a). After
all, an ordinary macro can expand to a variable that is not explicitly
required in the scope where the macro is used:

> (module a mzscheme (provide xa) (define xa 42))                 
> (module c mzscheme (require a) (provide xc) (define-syntax (xc stx) #'xa))
> (require c)
> (xc)
42

So why doesn't this work when we shift phases a little?

My real question is about using syntax objects with eval instead of
macros:

> (module a mzscheme (provide xa) (define xa 42))
> (module b mzscheme
(require-for-template mzscheme a) (provide xb) (define xb #'xa))
> (require b)
> (define ns (make-namespace))
> (eval xb ns)
reference to undefined identifier: xa

Now, I've tried all kinds of namespace and module tricks to get the
namespace ns to properly require the module a into the namespace ns, but
to no avail. I always get the same error. The only thing that works is
thi (proceeding from the previous):

> (require a)
> (namespace-attach-module (current-namespace) 'a ns)
> (parameterize ((current-namespace ns)) (namespace-require/copy 'a))
> (eval xb ns)
42

However, this seems just wrong. Require/copy is not a real require, and
I can't use this trick if I have multiple modules that export variables
with the same names. I don't even understand why the syntax object xb
could refer to the copied top-level variable xa in namespace ns. It
doesn't work that way with macro expansion:

> (module a mzscheme (provide xa) (define xa 42))
> (module b mzscheme
(require-for-template mzscheme a) (provide xb) (define xb #'xa))
> (require-for-syntax b)
> (define-syntax (foo stx) xb)
> (define xa 42)
> (foo)
reference to an identifier before its definition: xa in module: a

So. I want to use the wonderful syntax and module systems to construct
expressions with delicate bindings, and I want to _eval_ them instead of
returning them from a syntax transformer. Is this possible?

Thanks,


Lauri


Posted on the users mailing list.