Ralph Johnson wrote about Erlang this week, taking multiple angles worth reading, "Erlang, the next Java". One of them being how difficult it may be to update other sequential languages to Erlang's level of support for concurrency and distribution. Another being the relative importance (or not) of Erlang's sequential constructs being mostly functional.
Joe makes too much of functional programming because he says that lack of mutable state implies no locks. However, it is really lack of SHARED state that implies no locks. You could write processes in Basic, perl, or C. I'm sure that lots of people will look at Erlang and say "we can add that to our language". In my opinion, it is the concurrent programming aspects of Erlang that make it special, along with its mature implementation and powerful library designed for concurrency and reliability.The best candidate runtime in my opinion is Gambit Scheme. Gambit's already been used to achieve Erlang-like levels of concurrent threads, it's been used to implement an Erlang compiler, and it's been used to implement Termite a mostly-functional Scheme-like language with many Erlang-like concurrency features. (A point I've written about several times.)
I do not believe that other languages can catch up with Erlang anytime soon. It will be easy for them to add language features to be like Erlang. It will take a long time for them to build such a high-quality VM and the mature libraries for concurrency and reliability. So, Erlang is poised for success. If you want to build a multicore application in the next few years, you should look at Erlang.
I am convinced this approach would work well for "real" development, allowing the various language translators to run interpreted and compiled, just as Gambit itself is. Moreover, the translators could support sequential, shared-nothing implementations of various languages, relying on Gambit's threads and mailboxes to implement concurrent Erlang-like processes with asynchronous message passing among multiple languages running in the same Gambit OS process.
But then there's the rub. Ralph writes, "it is the concurrent programming aspects of Erlang that make it special".
This does make it special, but it's the simple, mostly-functional sequential aspects of Erlang that make it work so well. As soon as the sequential language is one with assignment and mutable memory, several unnecessary "issues" have to be dealt with. Even though the language is defining a shared-nothing, single-threaded process, these new issues overtake the simplicity of the concurrent message passing.
For example, what about "identity"? What about mutable lists, not to mention mutable, large object graphs? Erlang can play some tricks under the covers when "passing" immutable data among lightweight processes in the same OS process, potentially even in shared-memory among nodes on the same "physical" memory.
So a mutable sequential language gums up the concepts for the application programmer and gums up the mechanisms for the systems programmer. Javaspaces handles this fairly well for Java by keeping the mechanisms simple, yet the rules and the mechanisms (and copying) are significantly more complex and in the way of application developers. (Also pattern matching in Java is just cumbersome and not so nice to look at.)
These more "traditional" imperative languages (with or without "objects") were not designed for Erlang-like concurrency and are simply not as good a fit. Termite recognizes this and so provides a simpler, more-functional Scheme than Scheme R5RS.
Joe Armstrong writes in his HOPL III presentation (pdf):
Robert and I were convinced that one day we would have to add destructive operations to the language, but that we would wait until a problem that could not be solved with pure operations turned up.Erlang is special because its combination of sequential and concurrent features combine so well. Most languages have piled sequential feature on sequential feature. As Ralph Johnson notes:
This never happened.
Unlike Java or Smalltalk, where you only write threads/processes when you want concurrency, Erlang programmers use processes for modularity, reliability, and reuse. Then they get concurrency for free.