[e-lang] Alternative E loader
Kevin Reid
kpreid at mac.com
Fri Feb 19 08:32:39 PST 2010
On Feb 11, 2010, at 11:50, Thomas Leonard wrote:
> Hi all,
>
> The E documentation (e.g. the Walnut guide) suggests that .emaker
> files
> should be placed somewhere in classpath and then imported using
> <import:mypackage.myMaker>.
>
> If I want to depend on someone else's library then presumably I'm
> supposed to add their jar or directory to my classpath. However:
>
> - The classpath is a global (process-wide) namespace, so their emakers
> may override or conflict with existing ones.
>
> - Their jar may also introduce other files that affect the whole
> process (e.g. .safej files, giving their emakers access to unsafe
> Java code).
>
> - I have to mess around with extra -cpa options in the launcher
> scripts
> (which always has to be duplicated, to support Linux and Windows).
>
> - I can't add extra modules at runtime.
>
> - I can't depend on two libraries that use the same class names (e.g.
> two different versions of the same library).
Yes, these are all problems with the current system. Fixing it has
been on my mind for a while, under the name "module system".
The old draft code is at
http://switchb.org/darcs/e-modules/
I really need to write further about this, and consider your
contributions, but I haven't found the time to do a thorough review
since you wrote this first message; I'm just informing you of the
current situation and prior work.
On Feb 19, 2010, at 10:45, Thomas Leonard wrote:
> If accepted, it could also be used by rune to load the main program.
> This would allow all E programs to import emaker files from the same
> directory without any extra configuration (e.g. rune -cpa ...).
Per capability design principles, programs should not get automatic
read authority to what happens to be in the same directory. However, a
"run the program which consists of this module-directory's main entry
point" or other invocation mechanism which explicitly specifies *that
the directory access should exist* would be reasonable.
> In terms of speed, it is dramatically faster than <import>. This test
> case imports "testMaker.emaker" 100 times using both methods:
This is surprising. If true in general, then fixing whatever is slow
about <import> would probably significantly speed up a lot of E code.
Also, I note that your system still re-evaluates on every get/1;
eliminating this (though it raises shared-state issues until such time
as the results are audited DeepFrozen) ought to also be a speedup for
the situation where many other files use the same library emaker.
> - The getRoot method allows emakers to discover their own location. If
> this is a problem, we could replace it with "getTextWriter" and
> "getOutputStream" instead.
I have thought for a while that there ought to be an operation on file
objects to hide their pathnames, making them "virtual filesystem roots".
> - Rather than creating a whole new scope for each file, I just extend
> safeScope. This avoids having to keep reloading things. I'm assuming
> that safeScope's slots can be safely shared between files?
This is correct.
A number of additional points:
(1) The name "scope" is deprecated in favor of "env", as a matter of
terminological correctness; the corresponding code changes have not
been made, but new code should use the proper names within itself. (2)
Your explicit env manipulation can be simplified by using the
evaluation of code (untested example):
def [traceln__Resolver, fileScope] := e`
def traceln
traceln__Resolver
`.evalToPair(safeScope.withPrefix(...))
bind traceln := makeTraceln(fileFQName)
return fileScope.nestOuter()
However, this technique has the disadvantage of putting a spurious
traceln__Resolver variable in the env.
(3) You should not bind "safeScope" to the file env; the name
"safeScope" (should be safeEnv) denotes the *particular* env which has
no interesting authority, whereas yours does.
(4) When setting up an env, always do a nestOuter() last; this
operation makes all of the variables considered to be in an enclosing
scope rather than the current one, so that they are permitted to be
rebound. (This is the subsystem which prohibits { def x := 1; def x :=
2 } but permits { def x := 1; { def x := 2 } }.)
(5) Code which manipulates envs using state maps should be avoided, as
this discards the “binding” guard information which will be required
by guard-based auditing. However, there will arguably be larger
changes here as E-on-CL and E-on-Java are reconciled in the area of
env manipulation.
--
Kevin Reid <http://switchb.org/kpreid/>
More information about the e-lang
mailing list