Relation to Pi Calculus
Roger Price
rprice@REDACTED
Thu Nov 27 23:09:52 CET 2003
David Van Horn wrote [1]
> I've heard that Erlang is essentially an implementation of the untyped
> pi calculus. Is this a fair characterization? Which variant of the pi
> calculus most closely resembles Erlang (eg, asynchronous pi, distributed
> pi, seal, join, etc.)? Could someone provide examples of Erlang
> primitives that closely rememble the pi calculus primitives: input,
> output, and restriction?
Sorry for the much delayed comment - Richard Carlsson has already
explained [2] that Erlang is a lot larger than the pi calculus. Although
Erlang is not in itself an implementation of an untyped pi calculus, I
have found that it is a excellent vehicle for implementing emulators of pi
calculi "hardware".
I implemented a subset of Pierce and Turner's Pict [3] using the
equivalences
Pi calculus | Erlang
---------------+-------------
input process | explicit fun
output process | argument to function
path | Erlang process
My subset is asynchronous, higher-order, polyadic and concurrent with
automatic compile-time typing à la ML. It is not deterministic,
polymorphic (except for a few list operations), linear or sequenced. There
is no sub-typing. Although the implementation is potentially
distributable over more than one processor, I do not do this.
Erlang gives remarkably good performance. My first implementation was a
denotational semantics based interpreter in SML/NJ at 30 reductions/sec on
a 1GHz Intel PC. I re-wrote this in John Reppy's Concurrent ML and
achieved 300-500 reductions/sec [4]. I re-wrote again to issue Erlang
source code and achieved 10000 reductions per second for simple programs
such as factorial(n), n=1000. On a more ambitious program with heavy
animated graphics such as ant raids [5], I get up to 3000 reductions per
second.
Some notes on the emulator:
All Erlang processes run the same program which waits to receive explicit
funs and arguments, and applies them eagerly. Although there are
typically 2500 Erlang processes active at any one time, the pi calculus
concurrency is often only 20.
I rolled my own garbage collection of no-longer-needed paths. A path has
an average life of less than one second. Erlang's own garbage collection
seems to thrash on long runs: I fixed this by setting
erlang:system_flag(fullsweep_after,0).
Debugging in the pi calculus is _difficult_. When 2000 identical Erlang
processes talk themselves in a spaghetti deadlock, you need all the help
you can get. I added a lot of extra code and data structure to help out,
but this slows things down.
I would be very interested to hear of other attempts to use Erlang to
implement pi calculi.
Roger
[1] http://www.erlang.org/ml-archive/erlang-questions/200310/msg00108.html
[2] http://www.erlang.org/ml-archive/erlang-questions/200310/msg00141.html
[3] http://www.cis.upenn.edu/~bcpierce/papers/pict-design.ps
[4] To be fair, Concurrent ML is a _synchronous_ language and the
additional engineering needed for asynchronous one-way
communication really slows things down.
[5] "Swarm Intelligence", Eric Bonabeau, Marco Dorigo, Guy Theraulz,
chapter 2.2.3.
More information about the erlang-questions
mailing list