Discussion:
[e-lang] Question about E's history.
Constantine Plotnikov
2011-06-07 20:31:13 UTC
Permalink
Hi!

One of very nice features of E is that operation of listening for promise
with when returns a promise, so asynchronous operations could be composed
and it enables functional asynchronous programming. I'm interested whether
it is E's original invention or E has borrowed the idea from somewhere?

I'm also interested if there is some document that describes origins of core
ideas on which E's concurrency model is based.

Thanks,
Constantine
Mark S. Miller
2011-06-07 21:35:07 UTC
Permalink
On Tue, Jun 7, 2011 at 1:31 PM, Constantine Plotnikov <
Post by Constantine Plotnikov
Hi!
One of very nice features of E is that operation of listening for promise
with when returns a promise, so asynchronous operations could be composed
and it enables functional asynchronous programming. I'm interested whether
it is E's original invention or E has borrowed the idea from somewhere?
I have never seen it before E. And it was not in E for many of E's first
years. I distinctly remember Mark Seaborn, cc'ed, suggesting it. I think he
suggested it on e-lang but I'm not sure. I know it happened between 1998 and
2003, but also do not know more precisely when. Async programming in E was
*much* improved as a result.
Post by Constantine Plotnikov
I'm also interested if there is some document that describes origins of
core ideas on which E's concurrency model is based.
Concurrency Among Strangers at <erights.org/talks/promises/> and its
expansion in parts 3 (core ideas) and chapter 23 (origins) of my thesis.
Post by Constantine Plotnikov
Thanks,
Constantine
_______________________________________________
e-lang mailing list
http://www.eros-os.org/mailman/listinfo/e-lang
--
Cheers,
--MarkM
Tom Van Cutsem
2011-06-11 19:01:44 UTC
Permalink
Hi Constantine,

Having looked at various actor languages, I have not previously encountered
the type of asynchronous composability that when-expressions provide. So E
may be the first language to have introduced this feature.

About E's origins: in the paper "Concurrency among strangers", there is a
Mark S. Miller
2011-06-11 20:23:47 UTC
Permalink
Post by Tom Van Cutsem
Hi Constantine,
Having looked at various actor languages, I have not previously encountered
the type of asynchronous composability that when-expressions provide. So E
may be the first language to have introduced this feature.
About E's origins: in the paper "Concurrency among strangers", there is a
Jonathan Rees
2011-06-12 02:47:06 UTC
Permalink
Is this relevant as precedent? It was pretty well developed by 1984
http://en.wikipedia.org/wiki/MultiLisp
but I don't know how well developed it was regarding pipelining. I
suspect they got the 'promise' idea from Hewitt.

Jonathan
On Sat, Jun 11, 2011 at 12:01 PM, Tom Van Cutsem
Hi Constantine,
Having looked at various actor languages, I have not previously
encountered the type of asynchronous composability that when-
expressions provide. So E may be the first language to have
introduced this feature.
About E's origins: in the paper "Concurrency among strangers", there
Mark S. Miller
2011-06-12 09:11:36 UTC
Permalink
Post by Jonathan Rees
Is this relevant as precedent? It was pretty well developed by 1984
http://en.wikipedia.org/wiki/MultiLisp
Their promises were blocking, as were many other promises adapted to
sequential languages. Among such blocking promises for sequential languages,
their's many have be innovative -- I don't know. But in regards to the
issues raised in this thread, no I don't think it was first on anything
relevant.

The overall language's concurrency is essentially shared memory
multithreading added to Scheme. Even though promises could have help them
avoid the shared memory mistake, they didn't.
Post by Jonathan Rees
but I don't know how well developed it was regarding pipelining.
It had no pipelining.
Post by Jonathan Rees
I suspect they got the 'promise' idea from Hewitt.
Yes. Hewitt and Baker.
Post by Jonathan Rees
<http://en.wikipedia.org/wiki/MultiLisp>Jonathan
<http://en.wikipedia.org/wiki/MultiLisp>
Post by Tom Van Cutsem
Hi Constantine,
Having looked at various actor languages, I have not previously
encountered the type of asynchronous composability that when-expressions
provide. So E may be the first language to have introduced this feature.
About E's origins: in the paper "Concurrency among strangers", there is a
Tom Van Cutsem
2011-06-12 09:39:22 UTC
Permalink
Post by Jonathan Rees
I suspect they got the 'promise' idea from Hewitt.
Yes. Hewitt and Baker.
The earliest reference I can find on the notion of "futures" was in Hewitt
and Baker's 1977 paper named "The incremental garbage collection of
processes" <http://dspace.mit.edu/handle/1721.1/41969>.

In that paper, they seem to credit Friedman and Wise, and Hibbard, for a
similar idea.

Halstead, in his 1985 paper on Multilisp, cites the Baker & Hewitt 1977
paper, but also explicitly relates his futures to Hibbard's "eventuals" in
Algol 68. There is this footnote in Halstead's paper:

"These “futures” greatly resemble the “eventual values” of Hibbard’s Algol
68 [39]. The principal difference is that eventual values are declared as a
separate data type, distinct from the type of the value they take on,
whereas futures cannot be distinguished from the type of the value they take
on. This difference reflects the contrast between Algol’s philosophy of type
checking at compile time and the Lisp philosophy of run-time tagging of
data."

So it seems the principal novelty of Multilisp's futures was that they were
designed as transparent stand-ins for their values.

It's interesting to note the many design dimensions of promises/futures that
have been explored over the years, including:
- whether "touching" or "claiming" a future/promise is blocking or
non-blocking
- whether "touching" or "claiming" a future/promise is implicit (by
performing an operation that needs its value) or explicit (e.g. future.get()
in Java, promise claiming in Argus)
- whether the type Future<T> is distinct from the type T, in statically
typed languages
- whether futures/promises are created implicitly as the return value of a
message send or explicitly as in the Multilisp form "(future expr)"
- whether or not "pipelining" is supported
- whether or not futures/promises support proper exception propagation
- ...

Which only goes to say that "promise" and "future" are very overloaded terms
:-)

Cheers,
Tom
Post by Jonathan Rees
Post by Jonathan Rees
<http://en.wikipedia.org/wiki/MultiLisp>Jonathan
<http://en.wikipedia.org/wiki/MultiLisp>
Post by Tom Van Cutsem
Hi Constantine,
Having looked at various actor languages, I have not previously
encountered the type of asynchronous composability that when-expressions
provide. So E may be the first language to have introduced this feature.
About E's origins: in the paper "Concurrency among strangers", there is a
Dean Tribble
2011-06-12 09:50:05 UTC
Permalink
Post by Tom Van Cutsem
It's interesting to note the many design dimensions of promises/futures
- whether "touching" or "claiming" a future/promise is blocking or
non-blocking
- whether "touching" or "claiming" a future/promise is implicit (by
performing an operation that needs its value) or explicit (e.g. future.get()
in Java, promise claiming in Argus)
- whether the type Future<T> is distinct from the type T, in statically
typed languages
- whether futures/promises are created implicitly as the return value of a
message send or explicitly as in the Multilisp form "(future expr)"
- whether or not "pipelining" is supported
- whether or not futures/promises support proper exception propagation
Which only goes to say that "promise" and "future" are very overloaded
terms :-)
Certainly true. I always strongly tie it to the blocking issue: to me
"futures" are blocking, "promises" are non-blocking. To my mind, that
distinction is the most crucial, because it is a prerequisite for pipelining
support. I realize that the literature uses the terms inconsistently, but I
don't know of a more convenient terminology to use to distinguish those
cases.
Dean Tribble
2011-06-12 09:38:39 UTC
Permalink
Some E promise history:

E promises derive primarily from Joule channels, by way of the Xanadu
promise system. Joule was a massively concurrent programming language that
was a deliberate cross between actors and concurrent logic programming
languages. The Xanadu promise system was created by applying Joule channels
to a sequential language for pipe-lined, client-server communication. It was
contemporary with and independent of the Argus promises system. The E
language generalized that to "islands of sequential programming
communicating with promises".
Post by Jonathan Rees
Is this relevant as precedent? It was pretty well developed by 1984
http://en.wikipedia.org/wiki/MultiLisp
but I don't know how well developed it was regarding pipelining. I suspect
they got the 'promise' idea from Hewitt.
<http://en.wikipedia.org/wiki/MultiLisp>Jonathan
<http://en.wikipedia.org/wiki/MultiLisp>
Post by Tom Van Cutsem
Hi Constantine,
Having looked at various actor languages, I have not previously
encountered the type of asynchronous composability that when-expressions
provide. So E may be the first language to have introduced this feature.
About E's origins: in the paper "Concurrency among strangers", there is a
Constantine Plotnikov
2011-06-12 10:54:59 UTC
Permalink
This actually leads to question about origins of another idea that I learned
from E.

In E, several asynchronous components could share single event loop. Because
of this, the components are relatively cheap. In most other actor model
implementations, each component has own inbox and messages in it could be
retrieved in actor dependent order (for example priority messages could be
dispatched first).

When implementing AsyncScala and other implementations of E ideas, I have
noticed that it would be almost impossible to implement sane asynchronous
operation composition DSL without transparent sharing local event loop like
it was done in E. Local event loop provides context where memory could be
safely shared. In fact, the entire E Vat corresponds to classical actor.
The E objects are in fact some kind of sub-actor. And this makes
designating event handler trivial.

This idea is not uncommon to computer science. The GUI event loop implements
this idea to compose handlers for incoming events. Just imagine how GUI
event loop looked, if it was a single Erlang actor. Actually many Java
programs that I have seen use AWT event loop to organize safe interactions
of components (for example, IntelliJ IDEA uses GUI event loop to coordinate
writes to file system through its virtual file system layer). When something
should be done with shared component either inovkeLater or invokeAndWait is
called.

It would be interesting to know how this idea of Vat comes to E. I'm also
interested whether there are other Actor model implementations (that declare
that they such) where asynchronous components could share single event loop.

Thanks,
Constantine
Post by Dean Tribble
E promises derive primarily from Joule channels, by way of the Xanadu
promise system. Joule was a massively concurrent programming language that
was a deliberate cross between actors and concurrent logic programming
languages. The Xanadu promise system was created by applying Joule channels
to a sequential language for pipe-lined, client-server communication. It was
contemporary with and independent of the Argus promises system. The E
language generalized that to "islands of sequential programming
communicating with promises".
Post by Jonathan Rees
Is this relevant as precedent? It was pretty well developed by 1984
http://en.wikipedia.org/wiki/MultiLisp
but I don't know how well developed it was regarding pipelining. I suspect
they got the 'promise' idea from Hewitt.
<http://en.wikipedia.org/wiki/MultiLisp>Jonathan
<http://en.wikipedia.org/wiki/MultiLisp>
Post by Tom Van Cutsem
Hi Constantine,
Having looked at various actor languages, I have not previously
encountered the type of asynchronous composability that when-expressions
provide. So E may be the first language to have introduced this feature.
About E's origins: in the paper "Concurrency among strangers", there is a
Tom Van Cutsem
2011-06-12 13:17:48 UTC
Permalink
Yes, the notion of a "vat" as a container of objects is definitely another
one of E's distinguishing features. Your observation that a vat corresponds
to a classical actor is correct, which is why we ended up calling vats
"actors" in AmbientTalk (in hindsight, we probably should have sticked to E
terminology).

The notion of a "vat" as a container of objects is in itself not novel. This
was also a feature of what I have come to call the school of "active object"
languages. Denis Caromel's "ProActive" middleware for Java (and prior to
that, his Eiffel// extension to Eiffel), and Varela and Agha's "Salsa"
extension to Java are good examples of this. In active object models, one
typically distinguishes "active" from regular, or "passive" objects: the
active objects have their own message queue, and their behavior is typically
composed of passive objects.

What sets apart the E vat model from these models is that in E, one can
individually designate the objects internal to a vat from outside the vat.
In active object models, external objects can only designate the active
object as a whole, never one of its internal objects (just like in Erlang,
one can only ever reference a process Pid, never a data structure internal
to a process).

The beauty of the E vat model as opposed to e.g. the Erlang model, as I once
heard Mark explain it, is that internally, each vat can use traditional
imperative OOP to build more complex abstractions with ease, such that one
only has to deal with asynchrony and distributed computing issues when it is
strictly necessary to do so. By contrast, in Erlang, the notion of mutable
state is intimately tied to concurrent processes (one typically encapsulates
individual mutable data structures inside a single process), so that one
necessarily must think about issues of concurrent programming even for what
ought to be a simple, local data access. AFAICT, this is an important
software engineering argument that has hitherto been insufficiently
articulated by proponents of the vat/communicating event loops model.

Kind regards,
Tom
Post by Constantine Plotnikov
This actually leads to question about origins of another idea that I
learned from E.
In E, several asynchronous components could share single event loop.
Because of this, the components are relatively cheap. In most other actor
model implementations, each component has own inbox and messages in it could
be retrieved in actor dependent order (for example priority messages could
be dispatched first).
When implementing AsyncScala and other implementations of E ideas, I have
noticed that it would be almost impossible to implement sane asynchronous
operation composition DSL without transparent sharing local event loop like
it was done in E. Local event loop provides context where memory could be
safely shared. In fact, the entire E Vat corresponds to classical actor.
The E objects are in fact some kind of sub-actor. And this makes
designating event handler trivial.
This idea is not uncommon to computer science. The GUI event loop
implements this idea to compose handlers for incoming events. Just imagine
how GUI event loop looked, if it was a single Erlang actor. Actually many
Java programs that I have seen use AWT event loop to organize safe
interactions of components (for example, IntelliJ IDEA uses GUI event loop
to coordinate writes to file system through its virtual file system layer).
When something should be done with shared component either inovkeLater or
invokeAndWait is called.
It would be interesting to know how this idea of Vat comes to E. I'm also
interested whether there are other Actor model implementations (that declare
that they such) where asynchronous components could share single event loop.
Thanks,
Constantine
Post by Dean Tribble
E promises derive primarily from Joule channels, by way of the Xanadu
promise system. Joule was a massively concurrent programming language that
was a deliberate cross between actors and concurrent logic programming
languages. The Xanadu promise system was created by applying Joule channels
to a sequential language for pipe-lined, client-server communication. It was
contemporary with and independent of the Argus promises system. The E
language generalized that to "islands of sequential programming
communicating with promises".
Post by Jonathan Rees
Is this relevant as precedent? It was pretty well developed by 1984
http://en.wikipedia.org/wiki/MultiLisp
but I don't know how well developed it was regarding pipelining. I
suspect they got the 'promise' idea from Hewitt.
<http://en.wikipedia.org/wiki/MultiLisp>Jonathan
<http://en.wikipedia.org/wiki/MultiLisp>
Post by Tom Van Cutsem
Hi Constantine,
Having looked at various actor languages, I have not previously
encountered the type of asynchronous composability that when-expressions
provide. So E may be the first language to have introduced this feature.
About E's origins: in the paper "Concurrency among strangers", there is
Dean Tribble
2011-06-12 17:48:40 UTC
Permalink
Agreed. The larger islands of sequential programming in E were quite a
benefit for many kinds of programming,and is probably the key insight in teh
E computational model. A straightforward interpretation of "coarse-grained
actor" would have multiple capabilities into the shared state of the
"actor". The important addition is that, in a vat, the set of
capabilities available from outside the vat to the state in the vat can
change dynamically. Thus, I think of is as a worthy alternative to
fine-grained actors models.
Post by Tom Van Cutsem
Yes, the notion of a "vat" as a container of objects is definitely another
one of E's distinguishing features. Your observation that a vat corresponds
to a classical actor is correct, which is why we ended up calling vats
"actors" in AmbientTalk (in hindsight, we probably should have sticked to E
terminology).
The notion of a "vat" as a container of objects is in itself not novel.
This was also a feature of what I have come to call the school of "active
object" languages. Denis Caromel's "ProActive" middleware for Java (and
prior to that, his Eiffel// extension to Eiffel), and Varela and Agha's
"Salsa" extension to Java are good examples of this. In active object
models, one typically distinguishes "active" from regular, or "passive"
objects: the active objects have their own message queue, and their behavior
is typically composed of passive objects.
What sets apart the E vat model from these models is that in E, one can
individually designate the objects internal to a vat from outside the vat.
In active object models, external objects can only designate the active
object as a whole, never one of its internal objects (just like in Erlang,
one can only ever reference a process Pid, never a data structure internal
to a process).
The beauty of the E vat model as opposed to e.g. the Erlang model, as I
once heard Mark explain it, is that internally, each vat can use traditional
imperative OOP to build more complex abstractions with ease, such that one
only has to deal with asynchrony and distributed computing issues when it is
strictly necessary to do so. By contrast, in Erlang, the notion of mutable
state is intimately tied to concurrent processes (one typically encapsulates
individual mutable data structures inside a single process), so that one
necessarily must think about issues of concurrent programming even for what
ought to be a simple, local data access. AFAICT, this is an important
software engineering argument that has hitherto been insufficiently
articulated by proponents of the vat/communicating event loops model.
Mark S. Miller
2011-06-12 20:22:46 UTC
Permalink
[+kenneth.kahn, +danfuzz, +douglas (barnes), +ehud.shapiro, +carl, +chip]

On Sun, Jun 12, 2011 at 3:54 AM, Constantine Plotnikov <
***@gmail.com> wrote:
[...]
Post by Constantine Plotnikov
It would be interesting to know how this idea of Vat comes to E. I'm also
interested whether there are other Actor model implementations (that declare
that they such) where asynchronous components could share single event loop.
Agreed. The larger islands of sequential programming in E were quite a
benefit for many kinds of programming, and is probably the key insight in
[the] E computational model. [...]
Thanks. To explain how E arrived at this insight, a bit of history. The
following is all based on my old flawed memories, so cc'ing various involved
people for corrections and gap-filling. For those new to this thread, more
context can be found starting at <
http://www.eros-os.org/pipermail/e-lang/2011-June/013865.html>. To
contribute to this thread, please first subscribe at <
http://www.eros-os.org/mailman/listinfo/e-lang> or your messages will be
silently rejected.


Ehud Shapiro's 1983 paper "A subset of Concurrent Prolog and its
Interpreter" began the field of concurrent logic programming. That same
year, Shapiro (cc'ed) and Takeuchi's "Object-oriented programming in
concurrent Prolog" showed how to encode actors as a pattern of concurrent
logic programming, by reifying the "mailbox" as a stream of incoming
messages, provided by convention as a first argument to a goal. In 1987, Ken
Kahn, Dean Tribble, Danny Bobrow, and myself formed the Vulcan project at
PARC, initially to provide sugar to more directly express actors/objects on
top of this concurrent logic programming base.

Dean diagnosed and fixed a flaw in an early draft of "Vulcan: Logical
Concurrent Objects", and in so doing invented the inner-vs-outer send
technique which would later show up in Joule and become so important to our
E story below. An outer send would append onto the tail of a stream of
messages, adding a new message to be serviced after all previously queued
messages. An inner send, it you had the capabilities needed to express it,
would prepend a message onto the head of the stream of messages, to be
servived ahead of all previously queued messages.

Vijay Saraswat (hi Vijay -- it's good to see you here!) joined the Vulcan
project soon afterwards. We never really made much use of our sugar, finding
it didn't add much convenience and hid too much of the underlying power. And
a good thing too. The sugar would have baked in the one-mailbox-per-actor
assumption. By programming more directly on the base, we came to realize the
power of having a single actor (or concurrent logic programming perpetual
process) serve multiple mailboxes. This power is explained well in Ken
Kahn's "Objects: A Fresh Look" (the crucial text seems to be in the pages
missing between p217 and p220 in <
http://books.google.com/books?id=oiAkSgoiz6EC&lpg=PA207&ots=ShwbQwMNp9&dq=%22objects%20a%20fresh%20look%22%20kahn&pg=PA207#v=onepage&q=%22objects%20a%20fresh%20look%22%20kahn&f=false>).
Of the Vulcaneers, Ken (cc'ed) may have also originated this technique; I
don't remember. Ken, do you have the full paper online? Do you remember how
we came to realize the significance of this pattern?

Joule had two levels of semantic description. At the lower kernel layer,
Joule was a pure actors language with a single implicit mailbox per actor.
At the higher layer, which was more convenient for both users and
implementors, a Joule actor had multiple facets -- directly supporting the
power we'd discovered in the Vulcan project, that Ken's paper explains so
well. A Joule actor as a whole still processed only one event at a time, but
could service multiple mailboxes, one for each of its facets. In this way, a
Joule actor was a cheap unit of atomicity among multiple services being
provided from common state. I would count this as the first foundational
step away from the "active objects" view of actors that Tom mentioned. Joule
coupled this with (at this higher layer) direct support for inner-vs-outer
sends.
Dean Tribble
2011-06-12 21:21:33 UTC
Permalink
That all sounds right to me, and is much more thorough than my summary :).
I'll add one more tidbit about relation between Joule and E: the Joule
implementation used "thick pointers" where each object pointer had two
parts, a pointer a behavior and a pointer to state (where that was either a
simple value field or a heap-allocated record). That allowed multiple facets
to simply be different behavior pointers with the same state pointer. The
high level semantics of Joule had essentially a *static *set of facets per
Joule server (i.e., different behavior pointers), where the server was the
state boundary, as described below. However the runtime didn't have that
limitation. That difference was niggling, and we were finding places where
we might leverage the additional power that was syntactically not available.
As the E execution model crystallized, the fact that it could potentially
access that expressiveness seemed a confirmation that it was a good design
point.
Post by Mark S. Miller
[+kenneth.kahn, +danfuzz, +douglas (barnes), +ehud.shapiro, +carl, +chip]
On Sun, Jun 12, 2011 at 3:54 AM, Constantine Plotnikov <
[...]
Post by Constantine Plotnikov
It would be interesting to know how this idea of Vat comes to E. I'm also
interested whether there are other Actor model implementations (that declare
that they such) where asynchronous components could share single event loop.
Agreed. The larger islands of sequential programming in E were quite a
benefit for many kinds of programming, and is probably the key insight in
[the] E computational model. [...]
Thanks. To explain how E arrived at this insight, a bit of history. The
following is all based on my old flawed memories, so cc'ing various involved
people for corrections and gap-filling. For those new to this thread, more
context can be found starting at <
http://www.eros-os.org/pipermail/e-lang/2011-June/013865.html>. To
contribute to this thread, please first subscribe at <
http://www.eros-os.org/mailman/listinfo/e-lang> or your messages will be
silently rejected.
Ehud Shapiro's 1983 paper "A subset of Concurrent Prolog and its
Interpreter" began the field of concurrent logic programming. That same
year, Shapiro (cc'ed) and Takeuchi's "Object-oriented programming in
concurrent Prolog" showed how to encode actors as a pattern of concurrent
logic programming, by reifying the "mailbox" as a stream of incoming
messages, provided by convention as a first argument to a goal. In 1987, Ken
Kahn, Dean Tribble, Danny Bobrow, and myself formed the Vulcan project at
PARC, initially to provide sugar to more directly express actors/objects on
top of this concurrent logic programming base.
Dean diagnosed and fixed a flaw in an early draft of "Vulcan: Logical
Concurrent Objects", and in so doing invented the inner-vs-outer send
technique which would later show up in Joule and become so important to our
E story below. An outer send would append onto the tail of a stream of
messages, adding a new message to be serviced after all previously queued
messages. An inner send, it you had the capabilities needed to express it,
would prepend a message onto the head of the stream of messages, to be
servived ahead of all previously queued messages.
Vijay Saraswat (hi Vijay -- it's good to see you here!) joined the Vulcan
project soon afterwards. We never really made much use of our sugar, finding
it didn't add much convenience and hid too much of the underlying power. And
a good thing too. The sugar would have baked in the one-mailbox-per-actor
assumption. By programming more directly on the base, we came to realize the
power of having a single actor (or concurrent logic programming perpetual
process) serve multiple mailboxes. This power is explained well in Ken
Kahn's "Objects: A Fresh Look" (the crucial text seems to be in the pages
missing between p217 and p220 in <
http://books.google.com/books?id=oiAkSgoiz6EC&lpg=PA207&ots=ShwbQwMNp9&dq=%22objects%20a%20fresh%20look%22%20kahn&pg=PA207#v=onepage&q=%22objects%20a%20fresh%20look%22%20kahn&f=false>).
Of the Vulcaneers, Ken (cc'ed) may have also originated this technique; I
don't remember. Ken, do you have the full paper online? Do you remember how
we came to realize the significance of this pattern?
Joule had two levels of semantic description. At the lower kernel layer,
Joule was a pure actors language with a single implicit mailbox per actor.
At the higher layer, which was more convenient for both users and
implementors, a Joule actor had multiple facets -- directly supporting the
power we'd discovered in the Vulcan project, that Ken's paper explains so
well. A Joule actor as a whole still processed only one event at a time, but
could service multiple mailboxes, one for each of its facets. In this way, a
Joule actor was a cheap unit of atomicity among multiple services being
provided from common state. I would count this as the first foundational
step away from the "active objects" view of actors that Tom mentioned. Joule
coupled this with (at this higher layer) direct support for inner-vs-outer
sends.
Ken Kahn
2011-06-13 04:52:30 UTC
Permalink
Hi all.

"Objects a Fresh Look" can be found here:

http://users.ox.ac.uk/~oucs0030/Papers/objects_a_fresh_look.pdf

Regarding the origins of some the underlying intuitions perhaps we need to
go back to Carl Hewitt in the early and mid 1970s. Carl once motivated
Actors with the idea that programming in small should be more like
programming in the large (i.e., distributed computing). How do you program
interactions with a remote service? You send asynchronous messages. With
hindsight it might have been better to view the remote service as more like
a vat. Then actors would have naturally had multiple mailboxes.

Best,

-ken
Mark--
For what it's worth, while there may have been a dispute going on, I don't
recall being directly involved in it or feeling any "business panic". My
motivation was simple impatience and a desire to start coding something.
This may have dovetailed with something like a "business panic" on the part
of others, but I can't speak to that.
Cheers,
Doug
-----Original Message-----
Sent: Sunday, June 12, 2011 4:22pm
To: "Discussion of E and other capability languages" <
Subject: Re: [e-lang] Question about E's history.
[+kenneth.kahn, +danfuzz, +douglas (barnes), +ehud.shapiro, +carl, +chip]
On Sun, Jun 12, 2011 at 3:54 AM, Constantine Plotnikov <
[...]
Post by Constantine Plotnikov
It would be interesting to know how this idea of Vat comes to E. I'm also
interested whether there are other Actor model implementations (that
declare
Post by Constantine Plotnikov
that they such) where asynchronous components could share single event
loop.
Post by Constantine Plotnikov
Agreed. The larger islands of sequential programming in E were quite a
benefit for many kinds of programming, and is probably the key insight in
[the] E computational model. [...]
Thanks. To explain how E arrived at this insight, a bit of history. The
following is all based on my old flawed memories, so cc'ing various involved
people for corrections and gap-filling. For those new to this thread, more
context can be found starting at <
http://www.eros-os.org/pipermail/e-lang/2011-June/013865.html>. To
contribute to this thread, please first subscribe at <
http://www.eros-os.org/mailman/listinfo/e-lang> or your messages will be
silently rejected.
Ehud Shapiro's 1983 paper "A subset of Concurrent Prolog and its
Interpreter" began the field of concurrent logic programming. That same
year, Shapiro (cc'ed) and Takeuchi's "Object-oriented programming in
concurrent Prolog" showed how to encode actors as a pattern of concurrent
logic programming, by reifying the "mailbox" as a stream of incoming
messages, provided by convention as a first argument to a goal. In 1987, Ken
Kahn, Dean Tribble, Danny Bobrow, and myself formed the Vulcan project at
PARC, initially to provide sugar to more directly express actors/objects on
top of this concurrent logic programming base.
Dean diagnosed and fixed a flaw in an early draft of "Vulcan: Logical
Concurrent Objects", and in so doing invented the inner-vs-outer send
technique which would later show up in Joule and become so important to our
E story below. An outer send would append onto the tail of a stream of
messages, adding a new message to be serviced after all previously queued
messages. An inner send, it you had the capabilities needed to express it,
would prepend a message onto the head of the stream of messages, to be
servived ahead of all previously queued messages.
Vijay Saraswat (hi Vijay -- it's good to see you here!) joined the Vulcan
project soon afterwards. We never really made much use of our sugar, finding
it didn't add much convenience and hid too much of the underlying power. And
a good thing too. The sugar would have baked in the one-mailbox-per-actor
assumption. By programming more directly on the base, we came to realize the
power of having a single actor (or concurrent logic programming perpetual
process) serve multiple mailboxes. This power is explained well in Ken
Kahn's "Objects: A Fresh Look" (the crucial text seems to be in the pages
missing between p217 and p220 in <
http://books.google.com/books?id=oiAkSgoiz6EC&lpg=PA207&ots=ShwbQwMNp9&dq=%22objects%20a%20fresh%20look%22%20kahn&pg=PA207#v=onepage&q=%22objects%20a%20fresh%20look%22%20kahn&f=false
Post by Constantine Plotnikov
).
Of the Vulcaneers, Ken (cc'ed) may have also originated this technique; I
don't remember. Ken, do you have the full paper online? Do you remember how
we came to realize the significance of this pattern?
Joule had two levels of semantic description. At the lower kernel layer,
Joule was a pure actors language with a single implicit mailbox per actor.
At the higher layer, which was more convenient for both users and
implementors, a Joule actor had multiple facets -- directly supporting the
power we'd discovered in the Vulcan project, that Ken's paper explains so
well. A Joule actor as a whole still processed only one event at a time, but
could service multiple mailboxes, one for each of its facets. In this way, a
Joule actor was a cheap unit of atomicity among multiple services being
provided from common state. I would count this as the first foundational
step away from the "active objects" view of actors that Tom mentioned. Joule
coupled this with (at this higher layer) direct support for inner-vs-outer
sends.
Loading...