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