load module
Mark S. Miller
markm@caplet.com
Fri, 09 Jun 2000 14:56:37 -0700
At 04:32 AM 6/9/00 , Michael Neumann wrote:
>I hope this mailing-list is not only for E-language designer but also for
>E-user.
Correct. Welcome!
>1.)
>Is there any build-in function to load another E-file like a module?
>At the moment, I use:
> interp evalPrint(e__quasiParser valueMaker(<file:module.e> getText))
>but a command like:
> include("module.e") would be much better.
First, my compliments on figuring out this loading technique. I'm impressed.
There are three ways for E source code to appear in a file.
1) As an "E script", which is a file ending with ".e". This is the
equivalent of the "main" of a Java or C application. Unlike Java, these
need not be placed on the CLASSPATH. Instead, one merely says "e bar.e".
2) As an "Updoc script", which serves as executable documentation -- the
embedded examples can be automatically checked for accuracy. This is not
really supported yet, but see http://www.erights.org/e/Vector_updoc.txt to
get an idea. This form is not relevant to your question, so we won't deal
with it further here.
3) As an "EMaker", which is a file ending with ".emaker" and available on
the Java CLASSPATH (or otherwise made available as a resource according to
the appropriate ClassLoader). EMakers are E's modules. All reusable E
code should be placed in *.emaker files. Unfortunately, this is not yet
current practice, and probably won't be until further support is provided.
You aren't really supposed to load a *.e file from an E source file (of any
of the three types) except to do some kind of instrumented (or other
meta-level) execution of the loaded *.e script. When you do what to do so,
techniques like the one you discovered are fine.
To load a *.emaker from E source file, you use the "<import:...>" URI
expression. For example, if directory "d:/foo" is on your CLASSPATH and you
want to load "d:/foo/com/caplet/bar.emaker", the expression
"<import:com.caplet.bar>" would load this file and return the object that
the file evaluates to. This happens the first time. After that, this
object is cached and returned by further imports of that name.
Similarly, if "d:/foo.jar" is on your CLASSPATH, then the above expression
would load a contained "com/caplet/module/bar.emaker" member of that jar file.
If you have an importing cycle, then some of these import expressions will
be Promises that don't get fulfilled until the cycle unwinds. This is
rarely an issue that one would notice. (Joule's and Mozart's module systems
do likewise.)
Why the distinction between *.e files and *.emaker files? In order to
eventually support locally-untrusted code. Code in a *.e file starts in a
scope containing objects that grant vast amounts of authority -- essentially
all the authority of the OS process running it. Typically, this corresponds
to all the authority of the invoking user under that operating system. Once
E supports locally untrusted code (ie, we can remove the "otc-" qualifier
from http://www.erights.org/download/0-8-9/index.html#variants ) then
*.emaker files will evaluate in a scope that grants no authority whatsoever
for an object to effect the world outside of itself, except by using
computational resources. (Security note: This exception is sufficient to
leak information outward over covert channels.)
E Scripts, having a dangerous amount of authority, should be written to
import those EMakers containing the maker objects that make the instances
representing the real application, and invoke those makers passing in only
the subset of the user's authority properly needed (ie, the "least
authority") for running this application. One would then be able to read
only the invoking E Script in order to determine with what authority the
application will run.
Once the authority of *.emaker files is actually restricted in this way, I
will go on a campaign to change our style. In the meantime, only the reuse
issue you asked about causes code to be migrated from *.e files into
*.emaker files.
>2.)
>why I can call this:
> <swing:JFrame> new("MainWindow")
>but this results in an error:
> <swing:JButton> new("MyButton")
>
>Both Constructors in Java accept Strings.
>Or can't E disdinguish between different Java-classes, if there is more
>than one constructor with one argument.
MarcS is correct. My intention is to disable type-overloaded methods from
being invoked by unqualified identifiers, period. At the moment, the
implementation allows some arbitrary choice among the overloads to work.
This is terrible, as code that seems to work one day, or on one
implementation, may break the next day or on another implementation. I'll
fix this.
Thanks for the questions! As often happens, they stimulated me to writing
down things I desperately needed to write down.
Cheers,
--MarkM