[E-Lang] E Authorities was: Pending revision of E in a Walnut
Marc Stiegler
marcs@skyhunter.com
Wed, 22 Aug 2001 20:32:49 -0700
> ....(lot's of related material)
>
> Now, of course, I realize that a great deal of attention has been given
> precisely to I/O in E. :-) So let me pose a question: in the "Hello World
in
> E" example, where does the capability to send output, presumably to some
> default device, and presumably granted to the object that "println" is
> implemented on, come from, and how does the user typing come to have the
> capability/object that implements "println?" It may very well be that E
> routinely relies on things that category theorists would recognize as
> "monads" even if I myself do not at first blush.
Trying to sum up Paul's message here in one line, my attempt is, "whence
comes the first authorities in E?" This question has 3 answers, one for E
programs, one for eMakers, and one for caplets.
First a comment on the phrase, "ambient authority". I have been using the
term to mean "authority that you can get just because you have come to
life". I think Paul has been using it the same way. Apparently markm and
dean have a subtler meaning for it, which I will allow them to explain
another time. Meanwhile, I will refer to authority you have just because you
came to life as "default in-scope authority".
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.
eMakers come to life devoid of capabilities--truly and utterly devoid of
capabilites, to such an extent that Java applets in their sandboxes are
swimming with authority. Emakers get their authorities when they are
manufactured; indeed, the next version of Walnut will have an expanded
description of emakers, in which the "authorization" step is made explicit
in the naming conventions. The programmer about to use an emaker can look at
the parameters required and answer the question, "Does an emaker intended to
serve the function this claims to serve really need all this stuff?"
Caplets are the most complicated case. Caplets are a special stylized form
of emakers that are full fledged applications. They come to life with one
capability: the capability to talk to a powerbox, which is part of an E
application I describe as "the launcher". The launcher is an E app, with
full
authority, that is in the business of launching confined caplets.
The powerbox holds capabilities granted to the caplet, and mediates
acquisition of new authorities on the caplet's behalf.
In the current incarnation (which is in very crude rough draft form at this
time), some capabilities are granted during installation of the caplet on
the system, some are granted during operations, and a tiny handful of
capabilities are granted as default in-scope authority.
My current rendition of this system is so crude and incomplete that I am
reluctant to post it: it is literally what I am working on every day (well,
every day I don't get distracted by something else, like testing markm's
comm system :-), it is a big chunk of the work that needs to be done for our
DARPA contract.
Foolish fellow that I am, I will here publish the HelloWorld Caplet, with a
brief explanation, as a demonstration, not of how it should be done, nor of
how it will be done, but of what exists this afternoon, as a concrete
example of an approach. This approach does not require persistence, which
when available probably changes everything.
I don't know if what I do here has anything to do with monads, but I very
much doubt it :-)
--marcs
----Hello World Caplet----
def helloWorldCapletAuthor :near {
to getRequestedCaps() :near {"<requests></requests>"}
to run(powerbox, awt__uriGetter, swing__uriGetter) :near {
def traceln := powerbox optCap(powerbox TRACELN())
def helloWorldCaplet {
to init() {
traceln ("Hello World has run")
}
}
helloWorldCaplet init()
helloWorldCaplet
}
}
The method getRequestedCaps() returns an XML string that describes the
capabilities this caplet would like allocated during installation; this
could include
abilities to connect to the internet, to have read authority over particular
files, to have access to the system clock, etc. This method is called by the
installer, not by the powerbox or anyone else. The Hello World caplet needs
no authority beyond the default in-scope authority available in the current
version of the
system, so its requests are empty. Currently default in-scope authorities
include
--access to a FrameMaker for which the launcher/powerbox controls the
window's
frame area but the caplet controls the central contentPane, and
--access to an output stream where trace/debugging information
can be written.
--read authority on the subdirectory system beneath the directory where the
caplet's source resides, which is presumably where the caplet has stored
its own resources (and presumably not a place where the user has stored
all his most confidential files).
If we decide to make some of these non-default in the end, they can
be shut off just by rewriting the powerbox/installer so the grant must be
explicit during installation. Proper caplets should always be prepared to
deal with the possibility that they do not have the capability requested,
perhaps by requesting the capability in real-time through the powerbox,
perhaps through graceful degradation, perhaps by just shutting down. Of
course, for something like traceln, the powerbox could just pass a dummy
function that discards everything, the caplet would never know. And on the
third hand, if traceln were not an ambient function, to fulfill its purpose
the HelloWorld's getRequestedCaps would have to be rewritten to request
traceln (something along the lines of "<requests><traceln><why>So I can
print my message</why></traceln></requests>"; each capability the
caplet requests can be accompanied by a "why" tag, which is presented
by the installer to the user as the caplet's justification for
authorization).
The run() method launches the caplet with the authority to talk to the
powerbox (currently it also passes in awt and swing, which is part of my
development scaffolding and will be removed).
The powerbox has the method "optCap(capabilityName)" which can be called; if
a capability with that name exists, it will be returned. The powerbox method
TRACELN() returns the capability name for the trace/debug output
object; in practice, currently the println function is always passed in as
the traceln function. As you can probably see from this layout, the powerbox
keeps its capabilities in a map, and part of the powerbox's functionality is
to allow a caplet to subset the caplet's own capabilities for other
subcaplets by giving the powerbox a list of capabilities to use to create a
new sub-powerbox.
Anyway, the HelloWorldCaplet retrieves the traceln function from the
powerbox, and uses that to print "hello world" on the output device, which
is in practice the console.
The init() method is probably going to go away, and will be replaced by
actions taken directly in the run() method. A fuller caplet has other
methods which it can optionally implement, such as reactToPaste(frame,
object), which will be called by the powerbox when the user clicks the
Global Paste button in a window frame (access to the clipboard is mediated
by the powerbox, the clipboard is never directly granted to the caplet).
Like I said, this is a work in progress: this is the basic idea for one
crude way of putting it all together for caplets.
--marcs