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:
sum(f(x) for x in c)