[E-Lang] I/O with monads

Mark S. Miller markm@caplet.com
Thu, 23 Aug 2001 00:11:18 -0700


This is a long message.  If you skip it, please at least look at the 
conclusions at the bottom.

At 08:32 PM Wednesday 8/22/01, Marc Stiegler wrote:
>E programs, like Java programs and C++ programs, come to life full of
>default in-scope authority: E programs can reach directly into the Java API
>and do anything Java programs can do.

By "E programs", MarcS means *.e files, which are E's equivalent of a 
"main".  The high-authority scope they start in is called the "privileged 
scope", and intended to convey all the authority granted to that (jvm or 
whatever) process by the underlying OS.  Mixing concepts in the usual way, 
we say it represents "all the user's authority".  

The default E command line interpreter, or REPL, evaluates commands in 
exactly the same sort of scope, but with stdout, print, println, and stderr 
usually rebound according to the spawner of the REPL.  For example, Elmer 
rebinds these to print into the Elmer window rather than the process's 
stdout and stderr.  The current Updoc doesn't rebind these.  The upcoming 
Updoc will rebind these to capture their output and compare them (for 
testing purposes) with previously recorded output.

A REPL spawner is free to spawn a REPL using any Scope object the spawner 
itself has access to.  Dean's upcoming E "compiler" is structured to enable 
us to reify a runtime lexical scope into a Scope object, so that we will be 
able to spawn a REPL in a breakpointed execution context.  (Now if only we 
can figure out how to reconcile such breakpointing with event loop scheduling.)


Because *.e files have unrestricted authority, they are not importable.  
Rather, their job is only to import emakers and hand out least authorities 
to the resulting objects.  This corresponds to the KeyKOS big bang, in which 
the authorities representing ownership of the machine are subdivided and 
handed out to various primordial objects.

All of us doing E programming have found it productive to initially develop 
an application as a large E program, and only when it matures to turn its
pieces into reusable emakers constrained by POLA.  I think this development 
sequence is good, but I have mixed feelings about it.  In practice, we 
haven't been aggressive enough about taking that second step.  This probably 
means we need to better support this step with tools.

>eMakers come to life devoid of capabilities--truly and utterly devoid of
>capabilites, 

eMakers are importable, and are evaluated in the "universal scope".  Dean & 
I recently realized this scope contains binding for two kinds of objects: 


1) "universal constants" like "true", "false", and "null".  These only 
support computation within an object, so no capability discipline is 
violated by providing these by default.  These are morally equivalent to 
literals, but are accessed by name rather than special syntax.

(Notably, the universal constants include the default SlotGuard "settable", 
used in the default expansion of "var" if no guard is explicitly provided.  
Without this guard (or guards that delegate to this guard), an E program 
would be constrained to be side effect free. Even the ability to create a 
mutable variable in E is according to access to an appropriate capability, 
so it could have been controlled by capability discipline.  However elegant, 
we chose not to pursue this path as being both unnecessary and too painful. 
Instead, because the creation of mutable state is statically apparent, we 
chose post-facto auditing, such as for confinement, rather than pre-facto 
constraint.)


2) The elements in the universal scope that do grant some authority are:

* "E".  The "send(..)" and "sendOnly(..)" methods of "E" correspond to the 
eventual send operator "<-".  All these enable a pending delivery (of a 
message to a recipient) to be queued on this vat's pending delivery queue.  
Since this queue is a mutable vat-global variable, this ability-to-queue 
should potentially be considered an authority.  In writing this, I realize 
that "<-" should probably be expanded out of Kernel-E into these two calls, 
so that a non-standard spawner of an emaker can spawn it with a scope 
containing a non-standard "E" that virtualizes the queue.

* "import__uriGetter".  This is used in the expansion of the "<import:...>" 
sugar, and is the means by which one module imports another.  The only 
things importable by this construct are those Java classes deemed safe and 
confined as presented to the E programmer after "sugaring", and emakers, 
which are safe and confined by induction.  So import__uriGetter is not 
authority granting because it allows the importing of anything that would 
grant authority -- it doesn't.  Rather, because it implicitly provides read 
access to another vat-global variable -- the CLASSPATH.  Virtualization of 
the import__uriGetter should eventually provide the same kind of name space 
flexibility as that provided by Java's first class ClassLoaders.  Until 
then, we are stuck with that most horrible of things, a global name space.  
In this case, the global name space of fully-qualified package, class, and 
emaker names.

* Dean & I recently went through the exercise of classifying the universals 
into universal constants vs "others".  I know we decided we had a few more 
"others" than these two, but in looking at the source of ScopeSetup, I can't 
figure out what they are.  Dean?


At 08:13 PM Wednesday 8/22/01, Jonathan A Rees wrote:
>I'm still not sure how monads help with I/O problems.  Things like the
>ability to send output to a particular display are exactly what
>capabilities are for, but this can be handled in the usual way.
>
>If it were me I'd create a value or set of values representing the
>ability to do I/O (and other things) on the computer running a vat,
>and make them available in some initial interaction environment.  To
>allow loaded programs, or remote ones, to also use these things would
>require explicit transmission of the capability(ies) into the
>program's environment.
>
>This is vaguely like Scheme 48's command processor, which gives all
>sorts of capabilities (commands) to the user that aren't available to
>loaded programs.

As I read it, we're already doing exactly what Jonathan Rees recommends.
I will study the monad material, but if anyone can make a concrete 
suggestion about how monad ideas could benefit E, I'd find it greatly 
clarifying.  Thanks.


        Cheers,
        --MarkM