[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