An Incomplete History of Concurrent Programming Languages

Many computer scientists have tried to make concurrent programming easier over several decades. What can we learn from that work?

Disclaimer 1: You are the peer review. This isn't necessarily the truth, it's a blog post.

Disclaimer 2: This is an early draft with quite a few empty sections. Good enough to begin soliciting feedback for, not finished enough to feel satisfied.

1970s

Concurrent Pascal

Aside: I love the idea of Pascal. It feels somewhat sad to me that this language that's easy to compile and is quite readable got absolutely destroyed by Sun Microsystems in the 90s and its Java project. ZTH did some amazing work in the preceding two decades. Pascal, Modula-2, Oberon. I sometimes feel like the WinTel monopoly/monoculture did worse things to computer science than it did to consumer-facing software.

Concurrent Pascal [PDF] was Per Brinch Hansen's attempt to fix Pascal. GOTOs are out! Concurrency is in.

In Concurrent Pascal, two important concepts are "monitors" and "processes". A monitor is able to access shared data, such as global variables. Processes are not able to access this shared state. They must communicate with monitors via message passing.

External hardware is interfaced by another type called a "class". A class provides multiple processes access to a single device. Significantly, the compiler guarantees at compile time that no two processes can write to a single class.

The compiler has a lot of work to do in Concurrent Pascal. Hansen was convinced that a fairly rigid, hierarchical structure or processes, monitors and classes would ensure that the code was completely deadlock free.

Here is an example of a

type page = array[1..512] of char

type jobprocess =  
  process
    (input, output: diskbuffer);
  var
    block: page;
  cycle
    input.receive(block);
    update(block);
    output.send(block);
end  

Smalltalk-76

1980s

Erlang/OTP

1990s

ParC took inspiration from hardware description languages Verilog and VHDL. The language relies heavily on metaphor of events, signals and receivers.

Its authors' community is in a similiar space to [SystemC][], which was built to simulate many concurrent activities.

Hardware descriptions are different from normal coding in that the description is intrinsically parallel (with a large number of threads) and entirely static.

V-MS (Rick Munden (?))

To make use of the primitives, you include a header library (parc.h) and then you're able to create actor-like parallel blocks called a "process". ParC processes are mapped 1:1 to OS-threads. Communication between ParC processes is facilitated with channels (called pipes) under a message passing model.

Interesting language features include assertions that enforce the sequence of an event, e.g. asserting that one event occurs before another.

@?(<expression>) is an event that fires prior to the same event expression with an @, e.g. @(clock) and @?(clock), no other events can interleave.

Another is the "non-blocking assignment", with @= notation, that allows programmers to defer the value's assignment into some time in the future.

Here is example 12 from the their examples page, illustrating two sinks receiving messages:

#include <stdio.h>
#include "parc.h"

using namespace parc;

pipe<int> chn;

module top {  
public:  
  int i;
  top() {
    i = 1;
  }

  process p1 {
  start:
    for (; i < 5 ; i++) {
      mt_printf("p1> %d @ %3.3f\n",
                i,MyKern()->Now().D());
      chn.write(&i,1);
    }
  } a;

  process p2 {
    int d,r; 
  start:
    while (CHNS_DEAD != (r = chn.read(&d,1))) mt_printf("p2< %d @ %3.3f\n",
                                                        d,MyKern()->Now().D());
    printf("p2: done\n");
  } b;

};

  process p3 {
    int d,r; 
  start:
    migrate();
    while (CHNS_DEAD != (r = chn.read(&d,1))) mt_printf("p3< %d @ %3.3f\n",
                                                        d,MyKern()->Now().D());
    printf("p3: done\n");
  };


void test()  
{
  top t;

  p3 c;

  root()->StartAll();
}

int main(int argc,char **argv)  
{
  test();
}

2010s

Fortress

Chapel

Super Instruction Architecture (SIA) and its implementation (?) SIAL.

Mesham

References

http://www.cise.ufl.edu/research/ParallelPatterns/contents.htm