JoinCalculus is a
ProcessCalculus designed for
DistributedProgramming. It is a member of the
PiCalculus family of process calculi. It restricts
PiCalculus in several ways, but offers convenience in defining multi-way
join patterns, described more thoroughly below. Languages based on this include
JoCaml,
JoinJava, and
CeeOmega.
The feature distinguishing
JoinCalculus is its support for
join patterns (or
chords in
CeeOmega, as in striking multiple keys upon a piano). Instead of receiving each message individually, a join pattern waits until a whole pattern-matched collections of messages are available in the
MessageQueue, then handles them all simultaneously with one handler (potentially requiring replies to many different processes).
ActorsModel behavior would be a specific case of
JoinCalculus, in which one never requires more than one message to invoke a handler (see comparison to
ActorsModel on that page).
CeeOmega makes messages that return values synchronous (so the caller waits until the 'chord' is completed by other threads) and messages that don't return values asynchronous (so the caller can continue to deliver messages to other objects). Other possibilities would include use of
SendReceiveReplyEventually to support delayed replies from a chord or join pattern handler. In
CeeOmega, a handler that has only asynchronous messages will execute in its own thread (e.g. from a worker pool or freshly spawned), whereas a handler that has at least one synchronous message will run in one of the synchronized threads.
JoinCalculus programming model allows readily for the features of
ActorsModel (
FirstClass concurrent processes, transparent distribution, potential agent-based mobility). On the other hand, as with
PiCalculus, service accounting, transaction support (
TransactionalActorModel), some forms of security, and any sort of cross-process error handling, each become considerably more difficult than they were in
ObjectOriented and
ActorsModel because it is impractical to associate message processing with an activity initiated by any particular caller.
Skepticism: Without motivating examples, it is difficult to determine whether
join patterns simplify programming of process concurrency in a useful manner. In a sense, it seems that
JoinCalculus is attempting to unite some features of both
ActorsModel and
DataflowProgramming: the join patterns offer limited mechanism to combine outputs from other processes in a synchronous manner to determine the resulting behavior. Unfortunately,
JoinCalculus provides only half a solution. Fundamentally, joins require that the programmer orchestrate multiple processes in order to get work done, but
JoinCalculus (and the languages based upon it) offer no mechanism to perform such orchestration of processes.
Support for
DataflowProgramming, some sort of
FirstClass language for constructing and coordinating process configurations, would likely resolve the dilemma. Even with that level of support for actor configurations or whatnot, support for
join patterns would not be wholly redundant, as it would greatly reduce the need for actors to
explicitly perform storage of messages in order to usefully combine them. With plain old
ActorsModel one would require some sort of additional support to efficiently handle
DataflowProgramming over actor configurations, such as the ability to selectively wait on particular messages in the queue (as in
ErlangLanguage), or perhaps control over the message scheduler within a given configuration.
Reference
CeeOmega:
http://research.microsoft.com/en-us/um/cambridge/projects/comega/doc/comega_whatis.htm
It seems the various motivating examples for the various join patterns are: finite state buffers, reader-writer locks, etc. as objects.
JoinCalculus offers fine grained mechanisms for achieving these effects.
It's difficult to describe, but the join calculus provides (for me) an easy to understand, easy to write system for concurrent programming. I have yet, however, to write anything big in this.
Anyone else have more experience with it? --
TaralDragon
I have a similar question -- I've visited a bunch of sites (
JoinJava, JErlang,
CeeOmega, and an implementation based on the
BoostLibrary, as well as the
JoinCalculus site at Inria) and have found a bunch of examples of simple concurrency control examples, but I have yet to find any examples doing parallel programming (that is, using multiple CPUs to decrease the amount of wall-clock time a program requires). A couple examples that might be enlightening:
- Some sort of parallel reduce operation -- for example, something like the python expression
sum(f(x) for x in c)
- Some sort of wavefront computation, where, for instance, you can't compute the value of a[i,j] until you know the value of a[i-1,j] and a[i,j-1]
I don't see any reason why the join calculus wouldn't be suitable for those sort of programs, so I'm a little susprised there aren't any examples.
--
BillTrost
CategoryConcurrency