On Wed, Feb 11, 2009 at 8:07 PM, Mark Miller <[email protected]> wrote:
> On Wed, Feb 11, 2009 at 4:31 AM, Constantine Plotnikov
> <[email protected]> wrote:
>>
>> AFAIR on E mailing list there was discussion of about implementation
>> of E's operators in Scheme or some other variant of the LISP.
>
> http://homepage.mac.com/kpreid/elang/e-on-cl/
>
>
>>
>> It
>> should be also relatively easy to add Occam-like seq/par constructs
>> with loop variants.
>
> How would you add an Occam-like par construct to an imperative language
> while maintaining thread/vat isolation? It's not clear to me that that is
> possible.
>

The task is split into two parts. The first part is "all" operator,
that is easy to add to E as well, as we have discussed on e-lang list
(http://www.eros-os.org/pipermail/e-lang/2006-July/011361.html).

The basic form is the following:

all { as... } and { bs... } and { cs... }
all(a,b,c)

The "a","b", and "c" are eventual expressions and "as", "bs", and "cs"
are sequences of eventual statements.

The operator waits for all its arguments, and returns a promise that
either resolves to a tuple if all branches are successful of fails
with exception that contains partial evaluation results and branch
failures.

The loop form will be:

all for e in collection {
 s(e)
}

This form is basically map function that starts evaluation of all
asynchronous expressions at the same time and resolves to result when
all they are evaluated. The "all" operator is safe and quite easy to
implement. However it will execute all expressions in the same vat.

Lets now consider the "spawn " operator.

The basic form is:

spawn vatRunCapability {
  s...
}

The operator launches activity in the specified vat using
vatRunCapability. This vat is assumed to be attached to runner that
runs in parallel thread. And executes a sequence of statements in that
vat and the eventual result of the operator is the same as result of
the last statement.

The statements could not modify variables from lexical context and the
values from outer lexical context are passed according to the same
rules as arguments of eventual method invocation. This can be
implemented in the compiler, and I do not see significant problems
with it. The idea is to create an object in target vat that has the
same number of arguments as amount of used variables from lexical
closure, obtain a reference to this object and invoke the methods with
values of variables. The E has to have this functionality anyway to
boot new vats.

Now that we have both "all" and "spawn"  we could easily implement par
as composition of these operators. The "par" operator is an "all"
operator where all bodies and expressions are enclosed in implicit
"spawn" operator.

For the "par" operator we need to a capability to create new
lightweight parallel vats. The operator will accept this capability as
function vatFactory that returns a vat. The returned vat is assumed to
be a lightweight vat that is attached to threadpool-based runner or
something similar.

The par operator will look like the following:

par vatFactory { as... } and { bs... } and { cs... }
par vatFactory (a,b,c)

par vatFactory for e in collection {
 s(e)
}

So the first "par" form is translated as the following:

all {
  spawn vatFactory(){ as... }
} and {
  spawn vatFactory(){ bs... }
} and {
  spawn vatFactory(){ cs... }
}

Others are translate in a similar way. This is a basic translation, it
is possible to optimize it if resolvers are used directly instead of
promises when compiling "all" and "spawn" operators.

So the "par" is easy to implement in E on the compiler level. And I do
not see any conflicts with neither capability discipline nor with E's
principles.

Constantine
_______________________________________________
bitc-dev mailing list
[email protected]
http://www.coyotos.org/mailman/listinfo/bitc-dev

Reply via email to