From: Derek U. <Der...@on...> - 2002-10-11 01:11:34
|
> 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). So regardless of the import type, the program loads the specified file into a new DynamicEnvironment. For "environment-import", it traverses all bindings in that environment and pulls out any that do not correspond to macros. For "language-import" is pulls out any that do. Correct? Is the PREFIX argument optional, or do we have to explicitly use "#f". Does "language-import" still work correctly when done recursively across files? > 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. Actually, it seems more accurate to say that free variables encountered during macro expansion are always looked up in the current environment. > > (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.... That's fine. I viewed the intermediate functions as a way of explaining the implementation, more than anything else. By the way, why not have "local-env" just be (define local-env (interaction-environment)) in this case? > 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. Okay, I may not understand what the problem is (I haven't had the chance to play around with the new stuff), but I take it that you're trying to evaluate an expression in the "z:" environment, where it should be completely ignorant of the top-level bindings. After macro expansion, you should have (+ 1 (+ 1 5)) and the final result should be "7". Since we don't have first-class top-level environments, how about the following: * Importing an environment using a prefix adds a record of that prefix->environment mapping to a dictionary in the current environment. * A function "named-environment" does a lookup on that mapping. It returns a value equivalent to the value of "(interaction-environment)" or "(null-environment)", which can be passed as the third argument to eval. * The "named-environment" function is special, and environment-specific. It does not get imported across environments like normal functions. So your example would look like: (environment-import "test.scm" "z:") (eval '(g 5) (named-environment "z:")) Note that R5RS is careful to describe "(interaction-environment)" etc. as returning a *key*, not a first-class environment. I suppose that "(named-environment #t)" could always return the current evaluation environment key, regardless of the interaction environment, so (equal? (eval '(named-environment #t) (named-environment "z:")) (named-environment "z:")) should always return true. Since the JScheme builtin macros are non-hygenic anyway, the current semantics for importing a macro seem appropriate. I'd still like to see how ``hygenic'' language macros (where you can explicitly violate the hygiene) would work out. Derek |