[plt-scheme] Evaluation Across Modules (or Namespaces?)
I am having a problem understanding how eval works across modules and/or
namespaces. I have distilled my problem down to a fairly simple set of
examples.
At the top level, the following works (s is a structure to hold a
definition, def is a definition macro, act activates an instance of s
(creates a procedural object dynamically, app applies it). [In the actual
application, the args cannot be easily computed at expansion time and act
may create multiple instances with different args. In any case, I can't
easily create the procedural object in the macro.]
(define-struct s (args body f))
(define-syntax def
(syntax-rules ()
((d name args body ...)
(define name (make-s 'args
'(body ...)
#f)))))
(define (act an-s)
(set-s-f! an-s
(eval `(lambda ,(s-args an-s)
,@(s-body an-s)))))
(define (app an-s . args)
(apply (s-f an-s) args))
(define (my-f3 x) (* x x))
(def t1 (x) (* x x))
(act t1)
(printf "(app(t1 2) = ~a~n" (app t1 2))
(define (my-f2 x) (* x x))
(def t2 (x) (my-f2 x))
(act t2)
(printf "(my-f2 2) = ~a~n" (my-f2 2))
(printf "(app(t2 2) = ~a~n" (app t2 2))
(def t3 (x) (my-f3 x))
(act t3)
(printf "(my-f3 2) = ~a~n" (my-f3 2))
(printf "(app(t3 2) = ~a~n" (app t3 2))
If I run it, I get:
(app(t1 2) = 4
(my-f2 2) = 4
(app(t2 2) = 4
(my-f3 2) = 4
(app(t3 2) = 4
Which is what I want. However, I'd like to have the application part in a
module to be used by other modules. I created two modules a and b: [The
my-f3 definition in module a is just to have something callable in that
module.]
(module a mzscheme
(provide (all-defined))
(define-struct s (args body f))
(define-syntax def
(syntax-rules ()
((d name args body ...)
(define name (make-s 'args
'(body ...)
#f)))))
(define (act an-s)
(set-s-f! an-s
(eval `(lambda ,(s-args an-s)
,@(s-body an-s)))))
(define (app an-s . args)
(apply (s-f an-s) args))
(define (my-f3 x) (* x x))
)
(module b mzscheme
(provide (all-defined))
(require "a.ss")
(def t1 (x) (* x x))
(act t1)
(printf "(app(t1 2) = ~a~n" (app t1 2))
(define (my-f2 x) (* x x))
(def t2 (x) (my-f2 x))
(act t2)
(printf "(my-f2 2) = ~a~n" (my-f2 2))
(printf "(app(t2 2) = ~a~n" (app t2 2))
(def t3 (x) (my-f3 x))
(act t3)
(printf "(my-f3 2) = ~a~n" (my-f3 2))
(printf "(app(t3 2) = ~a~n" (app t3 2))
)
And get this when I run it:
(app(t1 2) = 4
(my-f2 2) = 4
. . a.ss::436: reference to undefined identifier: my-f2
So, it seems to only work for identifiers (like *) in the mzscheme
namespace. If I comment out the middle part of module b using a local
definition to b, I get the following:
(app(t1 2) = 4
(my-f3 2) = 4
. . a.ss::436: reference to undefined identifier: my-f3
So it doesn't seem to be evaluated in the namespace for a (where my-f3 is
defined either).
I hoped I could capture b's name space using (current-namespace) in the
macro expansion and parameterize in act as follows:
(module a1 mzscheme
(provide (all-defined))
(define-struct s (args body f ns))
(define-syntax def
(syntax-rules ()
((d name args body ...)
(define name (make-s 'args
'(body ...)
#f
(current-namespace))))))
(define (act an-s)
(parameterize ((current-namespace (s-ns an-s)))
(set-s-f! an-s
(eval `(lambda ,(s-args an-s)
,@(s-body an-s))))))
(define (app an-s . args)
(apply (s-f an-s) args))
(define (my-f3 x) (* x x))
)
(module b1 mzscheme
(provide (all-defined))
(require "a1.ss")
(def t1 (x) (* x x))
(act t1)
(printf "(app(t1 2) = ~a~n" (app t1 2))
(define (my-f2 x) (* x x))
(def t2 (x) (my-f2 x))
(act t2)
(printf "(my-f2 2) = ~a~n" (my-f2 2))
(printf "(app(t2 2) = ~a~n" (app t2 2))
(def t3 (x) (my-f3 x))
(act t3)
(printf "(my-f3 2) = ~a~n" (my-f3 2))
(printf "(app(t3 2) = ~a~n" (app t3 2))
)
But the results are identical.
Can someone enlighten me as to the error of my ways? The example code is in
the attached files.
Doug
-------------- next part --------------
A non-text attachment was scrubbed...
Name: top.ss
Type: application/octet-stream
Size: 725 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20060716/04e1bbd6/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: a.ss
Type: application/octet-stream
Size: 498 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20060716/04e1bbd6/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: b.ss
Type: application/octet-stream
Size: 426 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20060716/04e1bbd6/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: a1.ss
Type: application/octet-stream
Size: 609 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20060716/04e1bbd6/attachment-0003.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: b1.ss
Type: application/octet-stream
Size: 428 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20060716/04e1bbd6/attachment-0004.obj>