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
