My understanding is that GC is hard with multithread, particularly in a functional language where it's going to do some heavy lifting and needs to be very performant.
Or were you referring to OCaml in particular?
Also, if you can rely on the data-structures stored in your heap to be persistent, then you can tune the GC for it. The problem is that you need to make assumptions about the life-cycle of those data-structures. For example, the persistent data-structures being used in Scala or Clojure can be pretty heavy for the JVM's garbage collectors because they tend to produce junk that is neither short-term or long-term, thus invalidating the assumptions with which the JVM was built with. And generally that's OK, because the JVM's GCs can cope pretty well and if the need to optimize arises, well both Scala and Clojure are hybrids (just like OCaml), so you can just use mutable stuff if by profiling you see problems. So the theory is known and a decent concurrent GC can be built.
MOST problems are not easily parallelizable and you'll end up with concurrency. Concurrency means synchronizing and sending messages between processes. For example sending messages between processes means opening a socket of some sort, serializing the data you want to send and deserializing it on the consumer's side. That's extremely inneficient and there's no way you can end up with a pipeline of tens of millions of messages per second, but with 1:1 multi-threading you can [3]. Erlang can't cope with this load btw.
One other thing I like about working with threads is the user-friendliness. Yes, skipping over the perils of multi-threading which you can sort of avoid by using better libraries, you can easily do things like number crunching using "parallel collections", combine actors with reactive streams and futures, or fake asynchronous I/O by blocking threads. People nowadays tend to underestimate the utility of blocking threads, but it's pretty cool having an interface like `def fetchData: Future[Result]` that could be implemented on top of Netty (asynchronous I/O) or with JBDC (blocking I/O), only suffer a very small penalty and your process to still be able to reach 80% of CPU utilization.
So I think OCaml getting multi-threading support is a pretty big deal.
[1] http://akka.io/
JVM is obviously great a VM, and Scala brings most of the Erlang (and many other languages) features to the table. I am not sure about the fault tolerance. I need to look into how Akka implements the actors.
> Concurrency means synchronizing and sending messages between > processes.
I think in Erlang you can do only async sending and when the receiving process wakes up it gets it through one of the means you mentioned.
http://bartoszmilewski.com/2009/02/10/message-passing-sync-o...
> Erlang can't cope with this load btw.
This is what I am curious about. I have seen only one big system written in Erlang that was massive big. WhatsApp was also running in Erlang and they achieved something like 1M connection/server. That was impressive. I am wondering how could you do that with Akka?
> https://github.com/puniverse/quasar
I am following the development of these, starting to use it in Clojure soon, I am curious how it works out. Personally I prefer Aleph on the JVM for Clojure projects but wanna see what is happening in Quasar & co.