[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