From: Timothy H. <tim...@ma...> - 2002-10-10 08:34:23
|
Hi Derek, I've made a small change to your code base which seems to answer many of my concerns about macros and modules. (changed files included below) I've modified (environment-import FILE PREFIX) so that it only imports the non-macro symbols and I've added a procedure (language-import FILE) which imports only the macros (with no prefix). This approach has the nice feature that any macros defined in a module can be used to define the non-macro variables as expected, but loading in these bindings does not change the "language" of the current module. Importing a language from a file on the other hand explicitly imports just those macros in the file, and these macros can use the bindings in the current environment just by backquoting them. For example, if the following is in test.scm, then (language-import "test.scm" "zz:") ;; exposes f and g as zz:f and zz:g, using the value of a, while (environment-import "test.scm") ;; exposes a,b,c,d > (define a 1) > (define (b x) (set! a x)) ;; this throws an error as a module call! > (define (c x) (+ a x)) > (define-macro (f x) `(+ ,a ,x)) > (define-macro (g x) `(+ ,a (f ,x))) ;; this works as expected when the > language is imported > (define (d x) (g x)) ;; this works as expected when the environment is > imported > (define local-env jsint.Scheme.INTERACTION_ENVIRONMENT$) > (define (local-eval x) (eval x local-env)) I'll need to play with this for a while, but these two procedures seem to handle most of my needs for modularity. I think it might be a good idea to hide the other functionality so that environments and languages do not become first class objects, at least not now, as that can open up unforeseen consequences.... The separation of environment importing from language importing follows Christian Q's suggestion and seems to be to be a good one. One could of course import both the environment and language from a module. I like the idea of not allowing prefixes for language imports as it makes the tree of languages simpler to understand. I didn't check to see whether or not import-caching is being done, but it would be a good idea (i.e. create one dynamic environment per file and use that for all subsequent environment/language imports) This looks to be a simple and easy to understand macro/module system. Note also, that the "local-eval" procedure doesn't quite work as I would like as (environment-import "test.scm" "z:") (z:local-eval '(g 5)) --> (+ 1 (f 5)) so local-eval does not evaluate g as a macro but rather as a simple closure! It would be nice to have some sort of local eval that would evaluate an expression in the current module. ---Tim--- p.s. here are the changed files... |