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.
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.
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.)
At one point I wrote "parsers" for very small subset of Ruby and of Javascript. So small I need to use quotes. The parse trees were simply lists in Scheme ("s-expressions") and then some simple macros and functions to turn those trees into executable Scheme s-expressions. Since Gambit generates native code by way of compiling to C and it's runtime is compiled efficiently to native code, this approach essentially results in, for example, a Ruby-to-Gambit-to-C-to-Native code compiler.
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.
This never happened.
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:
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.