From: Derek U. <Der...@on...> - 2002-10-01 18:36:55
|
I don't know enough about the PLT unit modules to comment on future conflicts there, except in the actual use of symbols in the global environment: this system allows the importing program to choose the prefixes used. From my brief examination of the MzScheme documentation, their "namespace" mechanism is roughly similar, but they always add bindings to the local environment with no prefixes and (complicated) overriding rules. Regarding macro/compilation compatibility, the idempotence requirement saves us. If the imported code satisfies the requirement, there should be no way of telling whether the code was loaded at compile time or at run time, one time or multiple times. Of course, if the imported code changes between the time it was compiled and the time it was loaded, the idempotence requirement is violated. BTW, I've already modified the compiler to support this system. Just pass a class to "environment-import" instead of a file. The compiled class loads into the ``current'' environment instead of the interactive one. Derek -----Original Message----- From: Timothy Hickey [mailto:tim...@ma...] Sent: Monday, September 30, 2002 8:55 PM To: Derek Upham Subject: Re: [Jscheme-devel] Module implementation Hi Derek, We'll have to see what Ken thinks, but it looks like a very interesting extension. Ken and I had discussed earlier the idea of making Symbols into "Dynamic Variables," in a way similar to what you have done. It looks like this should allow current code to run unchanged but it will add an extra lookup for each free variable evaluation. I've been starting to feel the pinch from not having a module system and what I like about your system is that it is very simple (Hence easy to understand and easy to implement efficiently). My only concern is whether including this module system will prevent us from adding a "better" module system later (e.g. PLT's unit modules???), but I think any module system should be able to provide the kind of functionality yours is giving so that shouldn't be a problem. If we do check it in, then we'll need to modify the compiler to handle modules (shouldn't be hard). Have you thought about how the module system interacts with macros? At first glance it looks like macros should behave as expected when in an imported file.... This is exciting! ---Tim--- On Monday, September 30, 2002, at 06:27 PM, Derek Upham wrote: > This weekend I got a simple module system up and running. Simple, in > this > case, means that it is compatible with the "module:symbol" naming > convention > used in a lot of Scheme libraries. The steps were as follows: > > 1. Symbols no longer contain their values. There are separate > first-class > dynamic environments that contain the values. > > 2. Free variables are no longer Symbols after code analysis; they are > DynamicVariable objects, bound to a particular Symbol and > DynamicEnvironment. This means that free variables are always looked > up in > the environment they were defined in. > > 3. A new function "loading-environment" acts as "load", but all > definitions > are done in a new environment with ``standard'' initial bindings. The > new > environment is returned. You can pass that environment as the second > parameter to "eval", e.g., > > (let ((e (loading-environment "elf/basic.scm"))) > (eval 'iterate e)) > > The new environment is locked-down; you can't change any of its dynamic > bindings. > > 4. A new builtin (non-exposed) function "importBindings" runs through > all > the bindings in an environment and adds similar bindings to the current > environment. The new bindings can either be identical, or they can > have a > prefix attached. > > 5. A new function "environment-import" does both the loading and the > importing in succession. > > > > The upshot is that you can to the following: > >> (environment-import "elf/basic.scm" "foo:") > #t >> (foo:map* (lambda (x) (* x 2)) #(1 2 3)) > (2 4 6) >> (map* (lambda (x) (* x 2)) #(1 2 3)) > (map* {jsint.Closure ??[1] (x)} #(1 2 3) ) > > ==================================== > SchemeException:[[ERROR: undefined variable "map*"""]] > > Note that "map*" is renamed to "foo:map*" for us, but internally it > still > uses the plain "iterate" binding that is always does. You can also load > classes that use the normal "load()" method initialization convention: > >> (environment-import jlib.JLIB.class "jl:") > #t >> (jl:menu "m1" (jl:menuitem "foo")) > java.awt.Menu[menu0,label=m1,tearOff=false,isHelpMenu=false] > > If we pass #f for the prefix, nothing is prefixed; the function acts > like > "load". Assigning prefixes at load time gives more flexibility than > depending on hierarchical module trees (c.f. namespace aliases in C++). > Note that generic functions are merged correctly, not treated like other > variables. > > This mechanism only works for libraries that are idempotent; it can't > matter > how many times you've loaded the library, or which of the times you've > loaded it you're referring to. But a large class of Scheme code > satisfies > this restriction. (Locking-down the new environments catches at least > some > violations of this rule.) > > The big chunks seem to be complete; i'm now looking for corner cases > that > might hide bugs. Is this new functionality worth finishing up? > > Derek > > -- > Derek Upham > Senior Software Engineer > Ontain > 1750 112th Ave NE, Suite C-245 > Bellevue, WA 98004-3727 > Tel: 425-460-1886 > der...@on... > > > ------------------------------------------------------- > This sf.net email is sponsored by:ThinkGeek > Welcome to geek heaven. > http://thinkgeek.com/sf > _______________________________________________ > Jscheme-devel mailing list > Jsc...@li... > https://lists.sourceforge.net/lists/listinfo/jscheme-devel > |