Join-pattern

Last updated
Join-pattern
Paradigm concurrent computing, distributed programming
Developer INRIA Inria
Website Inria Join
Major implementations
Join Java, Polyphonic C#, Unified Parallel C, , Joins library, Boost.
Influenced
Join Calculus

Join-patterns provides a way to write concurrent, parallel and distributed computer programs by message passing. Compared to the use of threads and locks, this is a high level programming model using communication constructs model to abstract the complexity of concurrent environment and to allow scalability. Its focus is on the execution of a chord between messages atomically consumed from a group of channels.

Contents

This template is based on join-calculus and uses pattern matching. Concretely, this is done by allowing the join definition of several functions and/or channels by matching concurrent call and messages patterns. It is a type of concurrency pattern because it makes easier and more flexible for these entities to communicate and deal with the multi-threaded programming paradigm.

Description

The join-pattern (or a chord in ) is like a super pipeline with synchronisation and matching. In fact, this concept is summarise by match and join a set of message available from different message queues, then handles them all simultaneously with one handler. [1] It could be represented by the keywords when to specify the first communication that we expected, with the and to join/pair other channels and the do to run some tasks with the different collected messages. A constructed join pattern typically takes this form:

j.When(a1).And(a2). ... .And(an).Do(d) 

Argument a1 of When(a1) may be a synchronous or asynchronous channel or an array of asynchronous channels. Each subsequent argument ai to And(ai) (for i > 1) must be an asynchronous channel. [2]

More precisely, when a message matches with a chain of linked patterns causes its handler to run (in a new thread if it's in asynchronous context) otherwise the message is queued until one of its patterns is enabled; if there are several matches, an unspecified pattern is selected. [3]

Unlike an event handler, which services one of several alternative events at a time, in conjunction with all other handlers on that event, a join pattern waits for a conjunction of channels and competes for execution with any other enabled pattern. [4]

This flow diagram shows how the join pattern is executed by a general match with different channels (wait a chord) and synchronizes the resources (free or lock). JoinPatternFlowDiagram.png
This flow diagram shows how the join pattern is executed by a general match with different channels (wait a chord) and synchronizes the resources (free or lock).

Join-pattern is defined by a set of pi-calculus channels x that supports two different operations, sending and receiving, we need two join calculus names to implement it: a channel name x for sending (a message), and a function name x for receiving a value (a request). The meaning of the join definition is that a call to x() returns a value that was sent on a channel x<>. Each time functions are concurrently, triggers the return process and synchronizes with other joins. [5]

J::=//join patterns|x<y>//message send pattern|x(y)//function call pattern|J|JBIS//synchronization

From a client’s perspective, a channel just declares a method of the same name and signature. The client posts a message or issues a request by invoking the channel as a method. A continuation method must wait until/unless a single request or message has arrived on each of the channels following the continuation’s When clause. If the continuation gets to run, the arguments of each channel invocation are dequeued (thus consumed) and transferred (atomically) to the continuation’s parameters. [6]

Class diagram of the Join pattern JoinPatternClassDiagram.png
Class diagram of the Join pattern

In most of cases, the order of synchronous calls is not guaranteed for performance reasons. Finally, during the match the messages available in the queue could be stolen by some intervening thread; indeed, the awakened thread may have to wait again. [7]

History

π-calculus – 1992

The π-calculus belongs to the family of process calculi, allows mathematical formalisms for describing and analyzing properties of concurrent computation by using channel names to be communicated along the channels themselves, and in this way it is able to describe concurrent computations whose network configuration may change during the computation.

Join-Calculus – 1993

Join patterns first appeared in Fournet and Gonthier’s foundational join-calculus, an asynchronous process algebra designed for efficient implementation in a distributed setting. [8] The join-calculus is a process calculus as expressive as the full π-calculus. It was developed to provide a formal basis for the design of distributed programming languages, and therefore intentionally avoids communications constructs found in other process calculi, such as rendezvous communications.

Distributed Join-Calculus – 1996

The Join-Calculus is both a name passing calculus and a core language for concurrent and distributed programming. [9] That's why the Distributed Join-Calculus [10] based on the Join-Calculus with the distributed programming was created on 1996. This work use the mobile agents where agents are not only programs but core images of running processes with their communication capabilities.

JoCaml, Funnel and Join Java – 2000

JoCaml [11] [12] and Funnel [13] [14] are functional languages supporting declarative join patterns. They present the ideas to direct implement a process calculi in a functional setting.

Another extensions to (non-generic) Java, JoinJava, were independently proposed by von Itzstein and Kearney. [15]

Polyphonic C# – 2002

Cardelli, Benton and Fournet proposed an object-oriented version of join patterns for C# called Polyphonic C#. [16]

Cω – 2003

Cω is adaptation of join-calculus to an object-oriented setting. [17] This variant of Polyphonic C# was included in the public release of Cω (a.k.a. Comega) in 2004.

Scala Joins – 2007

Scala Joins is a library to use Join-Pattern with Scala in the context of extensible pattern matching in order to integrate joins into an existing actor-based concurrency framework.

JErlang – 2009

Erlang is a language which natively supports the concurrent, real time and distributed paradigm. Concurrency between processes was complex, that's why the project build a new language, JErlang (J stands for Join) using based on the Join-calculus.

Join-pattern in classic programming literature

"Join-patterns can be used to easily encode related concurrency idioms like actors and active objects." [18]

classSymmetricBarrier{publicreadonlySynchronous.ChannelArrive;publicSymmetricBarrier(intn){// Create j and init channels (elided)varpat=j.When(Arrive);for(inti=1;i<n;i++)pat=pat.And(Arrive);pat.Do(()=>{});}}
varj=Join.Create();Synchronous.Channel[]hungry;Asynchronous.Channel[]chopstick;j.Init(outhungry,n);j.Init(outchopstick,n);for(inti=0;i<n;i++){varleft=chopstick[i];varright=chopstick[(i+1)%n];j.When(hungry[i]).And(left).And(right).Do(()=>{eat();left();right();// replace chopsticks});}
classLock{publicreadonlySynchronous.ChannelAcquire;publicreadonlyAsynchronous.ChannelRelease;publicLock(){// Create j and init channels (elided)j.When(Acquire).And(Release).Do(()=>{});Release();// initially free}}
classBuffer<T>{publicreadonlyAsynchronous.Channel<T>Put;publicreadonlySynchronous<T>.ChannelGet;publicBuffer(){Joinj=Join.Create();// allocate a Join objectj.Init(outPut);// bind its channelsj.Init(outGet);j.When(Get).And(Put).Do// register chord(t=>{returnt;});}}
classReaderWriterLock{privatereadonlyAsynchronous.Channelidle;privatereadonlyAsynchronous.Channel<int>shared;publicreadonlySynchronous.ChannelAcqR,AcqW,RelR,RelW;publicReaderWriterLock(){// Create j and init channels (elided)j.When(AcqR).And(idle).Do(()=>shared(1));j.When(AcqR).And(shared).Do(n=>shared(n+1));j.When(RelR).And(shared).Do(n=>{if(n==1){idle();}else{shared(n-1);}});j.When(AcqW).And(idle).Do(()=>{});j.When(RelW).Do(()=>idle());idle();// initially free}}
classSemaphore{publicreadonlySynchronous.ChannelAcquire;publicreadonlyAsynchronous.ChannelRelease;publicSemaphore(intn){// Create j and init channels (elided)j.When(Acquire).And(Release).Do(()=>{});for(;n>0;n--)Release();// initially n free}}

Fundamental features and concepts

Application domain

Mobile agent

A mobile agent is an autonomous software agent with a certain social ability and most importantly, mobility. It is composed of computer software and data which can move between different computers automatically while continuing their executions.

The mobile agents can be used to match concurrency and distribution if one uses the Join-calculus. That's why a new concept named "distributed Join-calculus" was created; it's an extension of Join-calculus with locations and primitives to describe the mobility. This innovation use agents as running processes with their communication capabilities to allow an idea of location, which is a physical site expressing the actual position of the agent. Thanks to the Join-calculus, one location can be moved atomically to another site. [23]

The processes of an agent is specified as a set which define its functionality including asynchronous emission of a message, migration to other location. Consequently, locations are organized in a tree to represent the movement of the agent easier. With this representation, a benefit of this solution is the possibility to create a simple model of failure. Usually a crash of a physical site causes the permanent failure of all its locations. But with the join-calculus a problem with a location can be detected at any other running location, allowing error recovery. [23]

So the Join-calculus is the core of a distributed programming language. In particular, the operational semantics is easily implementable in a distributed setting with failures. So the distributed join-calculus treats channel names and location names as first class values with lexical scopes. A location controls its own moves, and can only move towards a location whose name it has received. This provides a sound basis for static analysis and for secure mobility. This is complete for expressing distributed configurations. In the absence of failure, however, the execution of processes is independent of distribution. This location transparency is essential for the design of mobiles agents, and very helpful for checking their properties. [23]

In 2007, an extension of the basic join calculus with methods which make agents proactive has come out. The agents can observe an environment shared between them. With this environment, it is possible to define shared variables with all agents (e.g. a naming service to discover agents between themselves). [24]

Compilation

Join-languages are built on top of the join-calculus taken as a core language. So all the calculus are analysed with asynchronous processes and the join pattern provides a model to synchronize the result. [9]
To do this, it exists two Compilers:

This two compiler works with the same system, an automaton.

let A(n) | B() = P(n) and A(n) | C() = Q(n) ;; 

It represents the consumption of message arrive at a completed join model. Each state is a possibly step for the code execution and each transitions is the reception of a message to change between two steps. And so when all messages are grab, the compiler execute the body join code corresponding to the completed model joint.

So in the join-calculus, the basic values are the names like on the example is A,B or C. So the two compiler representing this values with two ways.
Join compiler use a vector with Two slots, the first to the name it-self and the second to a queue of pending messages.
Jocaml use name like a pointer on definitions. This definitions store the others pointer of the others names with a status field and a matching date structure by message.
The fundamental difference is when the guard process is executed, for the first, it was verify if all names are the pending messages ready whereas the second use only one variable and access at the others to know if the model is completed. [9]

Recent research describe the compilation scheme as the combination of two basic steps: dispatching and forwarding. The design and correctness of the dispatcher essentially stems from pattern matching theory, while inserting an internal forwarding step in communications is a natural idea, which intuitively does not change process behavior. They made the observation that the worth observing is a direct implementation of extended join-pattern matching at the runtime level would significantly complicate the management of message queues, which would then need to be scanned in search of matching messages before consuming them. [25]

Implementations and libraries

There are many uses of the Join-patterns with different languages. Some languages use join-patterns as a base of theirs implementations, for example the Polyphonic C# or MC# but others languages integrate join-pattern by a library like Scala Joins [26] for Scala or the Joins library for VB. [27] Moreover, the join-pattern is used through some languages like Scheme to upgrade the join-pattern. [28]

JErlangCBJoins LibraryPolyphonic C#Parallel C#Scala JoinsF#SchemeJoin JavaHumeJoCaml
Patterns matchingYesYesYesYesYesYesYesYesYesYesYesYes
Scheduler between join-patternsYes : first matchYes : first/round robinYesYesYesYesYesYesNoYes : randomYes : first/round robinYes : random
GenericsYesYesNoNoYesYesNoNoNoNo
OverridingNoYesYesYesYesNoYesNoNo

Join Java

Join Java [29] is a language based on the Java programming language allowing the use of the join calculus. It introduces three new language constructs:

Example:

classJoinExample{intfragment1()&fragment2(intx){// Will return value of x to caller of fragment1returnx;}}

Example:

classThreadExample{signalthread(SomeObjectx){// This code will execute in a new thread}}

Join fragments can be repeated in multiple Join patterns so there can be a case when multiple Join patterns are completed when a fragment is called. Such a case could occur in the example below if B(), C() and D() then A() are called. The final A() fragment completes three of the patterns so there are three possible methods that may be called. The ordered class modifier is used here to determine which Join method will be called. The default and when using the unordered class modifier is to pick one of the methods at random. With the ordered modifier the methods are prioritised according to the order they are declared.

Example:

classorderedSimpleJoinPattern{voidA()&B(){}voidA()&C(){}voidA()&D(){}signalD()&E(){}}

The closest related language is the Polyphonic C#.

JErlang

In Erlang coding synchronisation between multiple processes is not straightforward. That's why the JErlang, [30] an extension of Erlang was created, The J is for Join. Indeed, To overcome this limitation JErlang was implemented, a Join-Calculus inspired extension to Erlang. The features of this language are:

operation()->receive{ok,sum}and{val,X}and{val,Y}->{sum,X+Y};{ok,mult}and{val,X}and{val,Y}->{mult,X*Y};{ok,sub}and{val,X}and{val,Y}->{sub,X-Y};endend
receive{Transaction,M}and{limit,Lower,Upper}when(Lower<=MandM<=Upper)->commit_transaction(M,Transaction)end
receive{get,X}and{set,X}->{found,2,X}end...receive{Pin,id}and{auth,Pin}and{commit,Id}->perform_transaction(Pin,Id)end
receiveprop({session,Id})and{act,Action,Id}->perform_action(Action,Id);{session,Id}and{logout,Id}->logout_user(Id)end...receive{Pin,id}and{auth,Pin}and{commit,Id}->perform_transaction(Pin,Id)end
receive{accept,Pid1}and{asynchronous,Value}and{accept,Pid2}->Pid1!{ok,Value},Pid2!{ok,Value}end

C++

Yigong Liu has written some classes for the join pattern including all useful tools like asynchronous and synchronous channels, chords, etc. It's integrated in the project Boost c++.

template<typenameV>classbuffer:publicjoint{public:async<V>put;synch<V,void>get;buffer(){chord(get,put,&buffer::chord_body);}Vchord_body(void_tg,Vp){returnp;}};

This example shows us a thread safe buffer and message queue with the basic operations put and get. [31]

C#

Polyphonic C#

Polyphonic C# is an extension of the C# programming language. It introduces a new concurrency model with synchronous and asynchronous (which return control to the caller) methods and chords (also known as ‘synchronization patterns’ or ‘join patterns’).

publicclassBuffer{publicStringget()&publicasyncput(Strings){returns;}}

This is a simple buffer example. [32]

MC#

MC# language is an adaptation of the Polyphonic C# language for the case of concurrent distributed computations.

publichandlerGet2long()&channelc1(longx)&channelc2(longy){return(x+y);}

This example demonstrates the using of chords as a synchronization tool.

Parallel C#

Parallel C# is based Polyphonic C# and they add some new concepts like movables methods, high-order functions.

usingSystem;classTest13{intReceive()&asyncSend(intx){returnx*x;}publicstaticvoidMain(string[]args){Test13t=newTest13();t.Send(2);Console.WriteLine(t.Receive());}}

This example demonstrates how to use joins. [33]

adds new language features to support concurrent programming (based on the earlier Polyphonic C#). The Joins Concurrency Library for C# and other .NET languages is derived of this project. [34] [35]

Scalable Join Patterns

It's an easy to use declarative and scalable join-pattern library. In opposite to the Russo library, [27] it has no global lock. In fact, it's working with a compare-and-swap CAS and Atomic message system. The library [36] use three improvements for the join-pattern :

  • Stealing message for unused resources (allowing barging);
  • Lazy queue saves both on allocation and potentially on interprocessor communication by avoiding allocate or enqueue with an optimistic fast-path;
  • A status "WOKEN" : ensures that a blocked synchronous caller is woken only once.

JoCaml

JoCaml is the first language where the join-pattern was implemented. Indeed, at the beginning all the different implementation was compiled with the JoCaml Compiler. JoCaml language is an extension of the OCaml language. It extends OCaml with support for concurrency and synchronization, the distributed execution of programs, and the dynamic relocation of active program fragments during execution. [37]

typecoins=Nickel|Dimeanddrinks=Coffee|Teaandbuttons=BCoffee|BTea|BCancel;;(* def defines a Join-pattern set clause * "&" in the left side of = means join (channel synchronism) * "&" in the right hand side means: parallel process * synchronous_reply :== "reply" [x] "to" channel_name * synchronous channels have function-like types (`a -> `b) * asynchronous channels have types (`a Join.chan) * only the last statement in a pattern rhs expression can be an asynchronous message * 0 in an asynchronous message position means STOP ("no sent message" in CSP terminology).   *)defput(s)=print_endlines;0(* STOP *);;(* put: string Join.chan *)defserve(drink)=matchdrinkwithCoffee->put("Cofee")|Tea->put("Tea");;(* serve: drinks Join.chan *)defrefund(v)=lets=Printf.sprintf"Refund %d"vinput(s);;(* refund: int Join.chan *)letnew_vendingserverefund=letvend(cost:int)(credit:int)=ifcredit>=costthen(true,credit-cost)else(false,credit)indefcoin(Nickel)&value(v)=value(v+5)&reply()tocoinorcoin(Dime)&value(v)=value(v+10)&reply()tocoinorbutton(BCoffee)&value(v)=letshould_serve,remainder=vend10vin(ifshould_servethenserve(Coffee)else0(* STOP *))&value(remainder)&reply()tobuttonorbutton(BTea)&value(v)=letshould_serve,remainder=vend5vin(ifshould_servethenserve(Tea)else0(* STOP *))&value(remainder)&reply()tobuttonorbutton(BCancel)&value(v)=refund(v)&value(0)&reply()tobuttoninspawnvalue(0);coin,button(* coin, button: int -> unit *);;(* new_vending: drink Join.chan -> int Join.chan -> (int->unit)*(int->unit) *)letccoin,cbutton=new_vendingserverefundinccoin(Nickel);ccoin(Nickel);ccoin(Dime);Unix.sleep(1);cbutton(BCoffee);Unix.sleep(1);cbutton(BTea);Unix.sleep(1);cbutton(BCancel);Unix.sleep(1)(* let the last message show up *);;

gives

Coffee Tea Refund 5 

Hume

Hume [38] is a strict, strongly typed functional language for limited resources platforms, with concurrency based on asynchronous message passing, dataflow programming, and a Haskell like syntax.

Hume does not provide synchronous messaging.

It wraps a join-pattern set with a channel in common as a box, listing all channels in an in tuple and specifying all possible outputs in an out tuple.

Every join-pattern in the set must conform to the box input tuple type specifying a '*' for non required channels, giving an expression whose type conform to the output tuple, marking '*' the non fed outputs.

A wire clause specifies

  1. a tuple of corresponding input origins or sources and optionally start values
  2. a tuple of output destinations, being channels or sinks (stdout, ..).

A box can specify exception handlers with expressions conforming to the output tuple.

dataCoins=Nickel|Dime;dataDrinks=Coffee|Tea;dataButtons=BCoffee|BTea|BCancel;typeInt=int32;typeString=string;showu=uasstring;boxcoffeein(coin::Coins,button::Buttons,value::Int)-- input channelsout(drink_outp::String,value::Int,refund_outp::String)-- named outputsmatch-- * wildcards for unfilled outputs, and unconsumed inputs(Nickel,*,v)->(*,v+5,*)|(Dime,*,v)->(*,v+10,*)|(*,BCoffee,v)->vendCoffee10v|(*,BTea,v)->vendTea5v|(*,BCancel,v)->letrefundu="Refund "++showu++"\n"in(*,0,refundv);venddrinkcostcredit=ifcredit>=costthen(servedrink,credit-cost,*)else(*,credit,*);servedrink=casedrinkofCoffee->"Cofee\n"Tea->"Tea\n";boxcontrolin(c::char)out(coin::Coins,button::Buttons)match'n'->(Nickel,*)|'d'->(Dime,*)|'c'->(*,BCoffee)|'t'->(*,BTea)|'x'->(*,BCancel)|_->(*,*);streamconsole_outpto"std_out";streamconsole_inpfrom"std_in";-- dataflow wiringwirecofee-- inputs (channel origins)(control.coin,control.button,coffee.valueinitially0)-- outputs destinations(console_outp,coffee.value,console_outp);wirecontrol(console_inp)(coffee.coin,coffee.button);

Visual Basic

Concurrent Basic – CB

An extension of Visual Basic 9.0 with asynchronous concurrency constructs, called Concurrent Basic (for short CB), offer the join patterns. CB (builds on earlier work on Polyphonic C#, Cω and the Joins Library) adopts a simple event-like syntax familiar to VB programmers, allows one to declare generic concurrency abstractions and provides more natural support for inheritance, enabling a subclass to augment the set of patterns. CB class can declare method to execute when communication has occurred on a particular set of local channels asynchronous and synchronous, forming a join pattern. [27]

ModuleBufferPublicAsynchronousPut(ByValsAsString)PublicSynchronousTake()AsStringPrivateFunctionCaseTakeAndPut(ByValsAsString)AsString_ WhenTake,PutReturnsEndFunctionEndModule

This example shows all new keywords used by Concurrent Basic: Asynchronous, Synchronous and When. [39]

Joins library (C# and VB)

This library is a high-level abstractions of the Join Pattern using objects and generics. Channels are special delegate values from some common Join object (instead of methods). [40]

classBuffer{publicreadonlyAsynchronous.Channel<string>Put;publicreadonlySynchronous<string>.ChannelGet;publicBuffer(){Joinjoin=Join.Create();join.Initialize(outPut);join.Initialize(outGet);join.When(Get).And(Put).Do(delegate(strings){returns;});}}

This example shows how to use methods of the Join object. [41]

Scala

There is a library in Scala called "Scala Joins" Scala Joins to use the Join-Pattern, it proposes to use pattern matching Pattern Matching as a tool for creating models of joins. You can find examples of the use of the join pattern in scala here: Join definitions in Scala.

The pattern matching facilities of this language have been generalized to allow representation independence for objects used in pattern matching. So now it's possible to use a new type of abstraction in libraries. The advantage of join patterns is that they allow a declarative specification of the synchronization between different threads. Often, the join patterns corresponds closely to a finite state machine that specifies the valid states of the object.

In Scala, it's possible to solve many problem with the pattern matching and Scala Joins, for example the Reader-Writer. [26]

classReaderWriterLockextendsJoins{privatevalSharing=newAsyncEvent[Int]valExclusive,ReleaseExclusive=newNullarySyncEventvalShared,ReleaseShared=newNullarySyncEventjoin{caseExclusive()&Sharing(0)=>ExclusivereplycaseReleaseExclusive()=>{Sharing(0);ReleaseExclusivereply}caseShared()&Sharing(n)=>{Sharing(n+1);Sharedreply}caseReleaseShared()&Sharing(1)=>{Sharing(0);ReleaseSharedreply}caseReleaseShared()&Sharing(n)=>{Sharing(n-1);ReleaseSharedreply}}Sharing(0)}

With a class we declare events in regular fields. So, it's possible to use the Join construct to enable a pattern matching via a list of case declarations. That list is representing by => with on each side a part of the declaration. The left-side is a model of join pattern to show the combinaison of events asynchronous and synchronous and the right-side is the body of join which is executed with the join model is completed.

In Scala, it's also possible to use the Scala's actor library [42] with the join pattern. For example, an unbounded buffer: [26]

valPut=newJoin1[Int]valGet=newJoinclassBufferextendsJoinActor{defact(){receive{caseGet()&Put(x)=>Getreplyx}}}

Actor-based concurrency is supported by means of a library and we provide join patterns as a library extension as well, so there are the opportunity to combine join patterns with the event-driven concurrency model offered by actors. Like you see in the example, it's the same way to use join pattern with actors, it just do it a list of case declaration in the method receive to show when the model is completed.

Practically the same tools are available in F# to use join pattern

Scala Join and Chymyst are newer implementations of the Join Pattern, improving upon Dr. Philipp Haller's Scala Joins.

Haskell

Join Language is an implementation of the Join Pattern in Haskell.

Scheme

The Join Patterns allows a new programming type especially for the multi-core architectures available in many programming situations with a high-levels of abstraction. This is based on the Guards and Propagation. So an example of this innovation has been implemented in Scheme . [28]

Guards is essential to guarantee that only data with a matching key is updated/retrieved. Propagation can cancel an item, reads its contents and puts backs an item into a store. Of course, the item is also in the store during the reading. The guards is expressed with shared variables. And so the novelty is that the join pattern can contains now propagated and simplified parts. So in Scheme, the part before / is propagated and the part after / is removed. The use of the Goal-Based is to divise the work in many tasks and joins all results at the end with the join pattern. A system named "MiniJoin" has implemented to use the intermediate result to solve the others tasks if it's possible. If is not possible it waits the solution of others tasks to solve itself.
So the concurrent join pattern application executed in parallel on a multi-core architecture doesn't guarantee that parallel execution lead to conflicts. To Guarantee this and a high degree of parallelism, a Software Transactional Memory (STM) within a highlytuned concurrent data structure based on atomic compare-and-swap (CAS) is use. This allows to run many concurrents operations in parallel on multi-core architecture. Moreover, an atomic execution is used to prevent the "false conflict" between CAS and STM. [28]

Other similar design patterns

Join Pattern is not the only pattern to perform multitasks but it's the only one that allow communication between resources, synchronization and join different processes.

See also

Related Research Articles

<span class="mw-page-title-main">F Sharp (programming language)</span> Microsoft programming language

F# is a functional-first, general-purpose, strongly typed, multi-paradigm programming language that encompasses functional, imperative, and object-oriented programming methods. It is most often used as a cross-platform Common Language Infrastructure (CLI) language on .NET, but can also generate JavaScript and graphics processing unit (GPU) code.

In computer science, the process calculi are a diverse family of related approaches for formally modelling concurrent systems. Process calculi provide a tool for the high-level description of interactions, communications, and synchronizations between a collection of independent agents or processes. They also provide algebraic laws that allow process descriptions to be manipulated and analyzed, and permit formal reasoning about equivalences between processes. Leading examples of process calculi include CSP, CCS, ACP, and LOTOS. More recent additions to the family include the π-calculus, the ambient calculus, PEPA, the fusion calculus and the join-calculus.

In computer science, message passing is a technique for invoking behavior on a computer. The invoking program sends a message to a process and relies on that process and its supporting infrastructure to then select and run some appropriate code. Message passing differs from conventional programming where a process, subroutine, or function is directly invoked by name. Message passing is key to some models of concurrency and object-oriented programming.

The actor model in computer science is a mathematical model of concurrent computation that treats an actor as the basic building block of concurrent computation. In response to a message it receives, an actor can: make local decisions, create more actors, send more messages, and determine how to respond to the next message received. Actors may modify their own private state, but can only affect each other indirectly through messaging.

In computer science, the Actor model and process calculi are two closely related approaches to the modelling of concurrent digital computation. See Actor model and process calculi history.

In computer science, future, promise, delay, and deferred refer to constructs used for synchronizing program execution in some concurrent programming languages. They describe an object that acts as a proxy for a result that is initially unknown, usually because the computation of its value is not yet complete.

Join Java is a programming language based on the join-pattern that extends the standard Java programming language with the join semantics of the join-calculus. It was written at the University of South Australia within the Reconfigurable Computing Lab by Dr. Von Itzstein.

In computing, a parallel programming model is an abstraction of parallel computer architecture, with which it is convenient to express algorithms and their composition in programs. The value of a programming model can be judged on its generality: how well a range of different problems can be expressed for a variety of different architectures, and its performance: how efficiently the compiled programs can execute. The implementation of a parallel programming model can take the form of a library invoked from a sequential language, as an extension to an existing language, or as an entirely new language.

Concurrent computing is a form of computing in which several computations are executed concurrently—during overlapping time periods—instead of sequentially—with one completing before the next starts.

<span class="mw-page-title-main">Scala (programming language)</span> General-purpose programming language

Scala is a strong statically typed high-level general-purpose programming language that supports both object-oriented programming and functional programming. Designed to be concise, many of Scala's design decisions are aimed to address criticisms of Java.

The actor model and process calculi share an interesting history and co-evolution.

JoCaml is an experimental functional programming language derived from OCaml. It integrates the primitives of the join-calculus to enable flexible, type-checked concurrent and distributed programming. The current version of JoCaml is a re-implementation of the now unmaintained JoCaml made by Fabrice Le Fessant, featuring a modified syntax and improved OCaml compatibility compared to the original.

The join-calculus is a process calculus developed at INRIA. The join-calculus was developed to provide a formal basis for the design of distributed programming languages, and therefore intentionally avoids communications constructs found in other process calculi, such as rendezvous communications, which are difficult to implement in a distributed setting. Despite this limitation, the join-calculus is as expressive as the full π-calculus. Encodings of the π-calculus in the join-calculus, and vice versa, have been demonstrated.

PROMELA is a verification modeling language introduced by Gerard J. Holzmann. The language allows for the dynamic creation of concurrent processes to model, for example, distributed systems. In PROMELA models, communication via message channels can be defined to be synchronous, or asynchronous. PROMELA models can be analyzed with the SPIN model checker, to verify that the modeled system produces the desired behavior. An implementation verified with Isabelle/HOL is also available, as part of the Computer Aided Verification of Automata (CAVA) project. Files written in Promela traditionally have a .pml file extension.

Joins is an asynchronous concurrent computing API (Join-pattern) from Microsoft Research for the .NET Framework. It is based on join calculus and makes the concurrency constructs of the Cω language available as a CLI assembly that any CLI compliant language can use.

ProActive Parallel Suite is an open-source software for enterprise workload orchestration, part of the OW2 community. A workflow model allows a set of executables or scripts, written in any language, to be defined along with their dependencies, so ProActive Parallel Suite can schedule and orchestrate executions while optimising the use of computational resources.

In computing, a channel is a model for interprocess communication and synchronization via message passing. A message may be sent over a channel, and another process or thread is able to receive messages sent over a channel it has a reference to, as a stream. Different implementations of channels may be buffered or not, and either synchronous or asynchronous.

Joyce is a secure programming language for concurrent computing designed by Per Brinch Hansen in the 1980s. It is based on the sequential language Pascal and the principles of communicating sequential processes (CSP). It was created to address the shortcomings of CSP to be applied as a programming language, and to provide a tool, mainly for teaching, for distributed computing system implementation.

In computer programming, the async/await pattern is a syntactic feature of many programming languages that allows an asynchronous, non-blocking function to be structured in a way similar to an ordinary synchronous function. It is semantically related to the concept of a coroutine and is often implemented using similar techniques, and is primarily intended to provide opportunities for the program to execute other code while waiting for a long-running, asynchronous task to complete, usually represented by promises or similar data structures. The feature is found in C# 5.0, C++20, Python 3.5, F#, Hack, Julia, Dart, Kotlin 1.1, Rust 1.39, Nim 0.9.4, JavaScript ES2017, Swift 5.5 and Zig, with some experimental work in extensions, beta versions, and particular implementations of Scala.

References

Notes

  1. Taral Dragon (October 25, 2009). "Join Calculus".
  2. Russo, Claudio V. (23 October 2008). "Join Patterns for Visual Basic". ACM SIGPLAN Notices. 43 (10): 10. doi:10.1145/1449955.1449770.
  3. "Parallel C#".
  4. Russo, Claudio V. (27 October 2008). "Join patterns for visual basic". ACM SIGPLAN Notices. 43 (10): 2. doi:10.1145/1449955.1449770.
  5. Fournet, Cédric; Gonthier, Georges (2002). Applied Semantics. Lecture Notes in Computer Science. Vol. 2395. Springer. pp. 268–332. CiteSeerX   10.1.1.4.4788 . doi:10.1007/3-540-45699-6_6. ISBN   978-3-540-44044-4.
  6. 1 2 3 4 5 6 Russo, Claudio V. (27 October 2008). "Join patterns for visual basic". ACM SIGPLAN Notices. 43 (10): 53–72. doi:10.1145/1449955.1449770.
  7. Russo, Claudio V. (23 October 2008). "Join Patterns for Visual Basic". ACM SIGPLAN Notices. 43 (10): 5. doi:10.1145/1449955.1449770.
  8. Russo, Claudio V. (23 October 2008). "Join Patterns for Visual Basic". ACM SIGPLAN Notices. 43 (10): 18. doi:10.1145/1449955.1449770.
  9. 1 2 3 Maranget, Luc; Le Fessant, Fabrice (25 September 2007). "Compiling Join-Patterns". Le Chesnay France.
  10. Fournet, Cédric; Gonthier, Georges; Levy, Jean-Jacques; Maranget, Luc (1996). CONCUR '96: Concurrency Theory. Lecture Notes in Computer Science. Vol. 1119. Le Chesnay: Concurrency Theory. pp. 406–421. doi:10.1007/3-540-61604-7_67. ISBN   978-3-540-61604-7.
  11. Fournet, Cedric; Le Fessant, Fabrice; Maranget, Luc; Schmitt, A. (2003). "JoCaml: A Language for Concurrent Distributed and Mobile Programming". Advanced Functional Programming. Lecture Notes in Computer Science. Vol. 2638. pp. 129–158. doi:10.1007/978-3-540-44833-4_5. ISBN   978-3-540-40132-2.
  12. Conchon, S.; Le Fessant, F. (1999). "Jocaml: Mobile agents for Objective-Caml". Proceedings. First and Third International Symposium on Agent Systems Applications, and Mobile Agents. pp. 22–29. doi:10.1109/ASAMA.1999.805390. ISBN   0-7695-0342-X. S2CID   14355301.
  13. Odersky, Martin (September 2000). "An overview of functional nets". Summer School, Caminha, Portugal, September 2000. 2395.
  14. Odersky, Martin (2000). "Functional Nets". Programming Languages and Systems. Lecture Notes in Computer Science. Vol. 1782. pp. 1–25. doi: 10.1007/3-540-46425-5_1 . ISBN   978-3-540-67262-3.
  15. Itzstein, G. S.; Kearney, D. (2001). "Join Java: An alternative concurrency semantics for Java". Technical Report ACRC-01-001, University of South Australia.
  16. Benton, N.; Fournet, C. (June 2002). "Modern concurrency abstractions for C#". In Proceedings of the 16th European Conference on Object-Oriented Programming (ECOOP 2002), Number 2374 in LNCS.
  17. Benton, N.; Cardelli, L. (2004). Modern Concurrency Abstractions for C#. ACM Transactions on Programming Languages and Systems. Vol. 26.
  18. Singh, Satnam (6 January 2007). "Higher Order Combinators for Join Patterns using STM". p. 1.
  19. 1 2 Aaron, Turon; Russo, Claudio V. (27 October 2011). Scalable Join Patterns (PDF). New York: Association for Computing Machinery. p. 4. ISBN   978-1-4503-0940-0.
  20. Aaron, Turon; Russo, Claudio V. (27 October 2011). Scalable Join Patterns (PDF). New York: Association for Computing Machinery. p. 1. ISBN   978-1-4503-0940-0.
  21. 1 2 Aaron, Turon; Russo, Claudio V. (27 October 2011). Scalable Join Patterns (PDF). New York: Association for Computing Machinery. p. 3. ISBN   978-1-4503-0940-0.
  22. Aaron, Turon; Russo, Claudio V. (27 October 2011). Scalable Join Patterns (PDF). New York: Association for Computing Machinery. p. 2. ISBN   978-1-4503-0940-0.
  23. 1 2 3 Fournet, Cédric; Gonthier, Georges; Levy, Jean-Jacques; Maranget, Luc; Remy, Didier (1996). CONCUR '96: Concurrency Theory. Lecture Notes in Computer Science. Vol. 1119. Le Chesnay: Concurrency Theory. pp. 406–421. doi:10.1007/3-540-61604-7_67. ISBN   978-3-540-61604-7.
  24. Maludzinski, Slawomir; Dobrowolski, Grzegorz (2007). "Agent Environment and Knowledge in Distributed Join Calculus". Multi-Agent Systems and Applications V. Lecture Notes in Computer Science. Vol. 4696. pp. 298–300. doi:10.1007/978-3-540-75254-7_30. ISBN   978-3-540-75253-0.
  25. Ma, Qin; Maranget, Luc (5 April 2004). CONCUR 2004 – Concurrency Theory. Lecture Notes in Computer Science. Vol. 3170. INRIA. pp. 417–431. CiteSeerX   10.1.1.499.8443 . doi:10.1007/978-3-540-28644-8_27. ISBN   978-3-540-22940-7. S2CID   9956643.
  26. 1 2 3 Haller, Phillip; Van Cutsem, Tom (2008). Coordination Models and Languages. Lecture Notes in Computer Science. Vol. 5052. Lausanne: Coordination Models and Languages. pp. 1–15. CiteSeerX   10.1.1.210.1242 . doi:10.1007/978-3-540-68265-3_9. ISBN   978-3-540-68264-6.
  27. 1 2 3 Russo, Claudio V. (23 October 2008). "Join Patterns for Visual Basic". ACM SIGPLAN Notices. 43 (10): 53–72. doi:10.1145/1449955.1449770.
  28. 1 2 3 Sulzmann, Martin; S. L. Lam, Edmund. "Parallel Join Patterns with Guards and Propagation". Denmark.
  29. Hopf, J.; von Itzstein, G.; Stewart, al. (2002). Hardware Join Java: A High Level Language For Reconfigurable Hardware Development. Hong Kong: IEEE. Archived from the original on 2013-02-19.
  30. Plociniczak, Hubert; Eisenbach, Susan (2010). "JErlang: Erlang with Joins". Coordination Models and Languages. Lecture Notes in Computer Science. Vol. 6116. Springer. pp. 61–75. Bibcode:2010LNCS.6116...61P. doi: 10.1007/978-3-642-13414-2_5 . ISBN   978-3-642-13413-5.
  31. Liu, Yigong (2007–2009). "Join – Asynchronous Message Coordination and Concurrency Library".
  32. "Introduction to Polyphonic C#".
  33. "Parallel C#". Archived from the original on 2013-11-26.
  34. Hanus, Michael (January 2007). The Joins Concurrency Library. Vol. 4354. ISBN   978-3-540-69608-7.
  35. "Comega".
  36. Aaron, Turon; Russo, Claudio V. (27 October 2011). Scalable Join Patterns (PDF). New York: Association for Computing Machinery. ISBN   978-1-4503-0940-0.
  37. Fournet, Cedric; Le Fessant, Fabrice; Maranget, Luc; Schmitt, Alan (2003). "JoCaml: a Language for Concurrent Distributed and Mobile Programming" (PDF). Advanced Functional Programming. Lecture Notes in Computer Science. Springer-Verlag. pp. 129–158.
  38. Hammond/Michaelson/Sun – Programming reactive systems in Hume
  39. "Concurrent Basic". Archived from the original on 2015-04-25.
  40. Russio, Claudio (2007). "The Joins Concurrency Library". Practical Aspects of Declarative Languages. Lecture Notes in Computer Science. Vol. 4354. Cambridge: Practical Aspects of Declarative Languages. pp. 260–274. CiteSeerX   10.1.1.187.8792 . doi:10.1007/978-3-540-69611-7_17. ISBN   978-3-540-69608-7.
  41. "The Joins Concurrency Library".
  42. Haller, Phillip; Odersky, Martin (June 2007). "Actors that unify threads and events". Coordination Models and Languages. Springer. doi:10.1007/978-3-540-72794-1_10.
  43. MONSIEUR, Geert (2010), Pattern-based Coordination in Process-based Service Compositions, Leuven Belgium: Katholiek Universiteit Leuven, p. 68
  44. MONSIEUR, Geert (2010), Pattern-based Coordination in Process-based Service Compositions, Leuven Belgium: Katholiek Universiteit Leuven, p. 70