Monday, 17 September 2007

Why Erlang Is Not The (Whole) Answer

When discussing the problems of concurrency and parallelism, remarkably often someone pipes up with "You should just use Erlang!" This is frustrating.

I think by "Erlang" they mainly mean no-shared-memory, message passing processes. That is definitely a good way to structure many systems --- it avoids the pit of all evil, concurrency with unrestricted shared memory. But for many problems it is not a good fit. Many problems are fundamentally about concurrent updates to shared state, for example:

  1. Transfers between bank accounts
  2. Object interactions in a virtual world
  3. Scripts manipulating the DOM in a parallel browser

The right abstraction for these problems is atomic updates, a.k.a. transactions. In each transaction we want to read multiple values, do some computation, and update multiple values. We want the program behaviour to be as if transactions happen one at a time (atomicity), but we actually want updates to execute in parallel when they do not interfere.

This does not map well to pure message-passing systems in general. You can implement ad-hoc solutions to these transactional problems in most languages, including Erlang. You can even implement some sort of transactional memory in Erlang. But the language --- message passing in particular --- isn't helping you here. To cleanly express solutions to these problems we need a language (or if we're lucky, a library) which can directly describe shared state and atomicity, and implement them with some degree of parallelism.

Transactions are no panacea either! The point is just that message passing is often not the best way to express concurrency, and therefore the ideal system for parallel programming will contain more concurrency features than just message passing.


  1. Have you seen the Vodka language? It's the project of someone working on their thesis on building a highly concurrent language based on the Join Calculus and Petri Nets:
    It's got some interesting ideas, and many concepts can be built as libraries, for example, transactions:

  2. Robert O'Callahan17 September 2007 21:24

    Sounds cool. However, for performance-critical code I'm always going to be wary of languages like this (and Haskell) that rely on clever encodings of state. To get really good code, the compiler will have to work really hard to ensure that high-level state abstractions are compiled into plain hardware state with no extra rubbish. Maybe it can be done, but it adds a lot of complexity and uncertainty to the implementation story.

  3. I've seen some of Brendan Eich's blogs about concurrency and javascript, but I'm still wondering: what are the chances of fitting STM into JS?
    When doing DOM manipulation in JS I've often wished for a suspendRedraw like SVG has; it seems to me that STM transactions would work for that and provide a host of other benefits besides.

  4. If you want transactions, just use databases.

  5. Five big words: "we actually want updates to execute in parallel when they do not interfere"
    I found myself thinking back to days when I was concerned by such as NMIRQ.

  6. This is an old post but it is still relevant. I don't understand your point. In erlang you can send a message to a process X, then X is performing some hard work and when it's done, you get back an anwser which says "ok, done, i have a new modified state" or "error, my state hasn't changed because this is a transaction ... there is the error: ..."