views:

669

answers:

5

Microsoft's new F# programming language provides the powerful combination of functional programming (first-class lexical closures and tail calls) with an efficient concurrent garbage collector that makes it easy to leverage multicores.

OCaml, Haskell, Erlang and all free Lisp and Scheme implementations that I know of do not have concurrent GCs. Scala and Clojure have a concurrent GC but no tail calls.

So there appear to be no open source programming languages that combine these features. Is that correct?

A: 

Not really an answer to your question, but to my best knowledge, F# uses the standard .NET garbage collector, which is not concurrent; all threads are stopped during GC.

Edit : my mistake, there is a concurrent GC in multiprocessor mode.

Stephan Leclercq
.NET supports a concurrent GC (at least for level 2 collections), see http://blogs.msdn.com/clyon/archive/2004/09/08/226981.aspx and http://www.julmar.com/blog/mark/PermaLink,guid,3670d081-0276-48e6-b97d-1b644093b52e.aspx
Rob Walker
+4  A: 

Latest version of GHC supports parallel GC. See the release notes.

Claymore
I was going to note this, too, but parallel and concurrent garbage collection aren't the same thing.
mipadi
Indeed. That's why Haskell's GC doesn't scale.
Jon Harrop
Err...it depends on what you're trying to scale. As I pointed out above, MS actually provides a non-concurrent GC because it scales better (in terms of throughput) than their concurrent one.
Curt Sampson
@Curt: Scaling and throughput are not the same thing. The non-concurrent parallel "server" GC option for .NET sacrifices latency to improve throughput. If you run a program with a thread for each core where only one thread allocates heavily then you will see that the server GC scales far worse than the default concurrent GC because that one thread degrades the performance of all other threads with non-concurrent GC. Haskell and the default JVM GC exhibit the same problem. Hence I said that Haskell's GC does not scale.
Jon Harrop
I fail to see how, if you're generating a lot of garbage and you don't care about latency (say it's an analysis program that runs for a few hours and you just look at the final result), a parallel GC whose speed increases (i.e., you spend less wall clock time doing GC) is not "scaling." Does the program not run faster (in wall clock time) as you give the GC more cores?
Curt Sampson
@Curt: You are neglecting the contribution to the scalability from the stop-the-world phase, which is the dominant contribution.
Jon Harrop
A: 

Java is supposedly adding tail calls. When that happens, clojure will get them. In the meantime, you can get them manually with the loop/recur mechanism.

Lou Franco
loop/recur will get you tail *recursion* (tail calls to self) but not general tail calls.
bendin
That's right, bendin. Imperative loops are not a substitute.
Jon Harrop
+3  A: 

Scala has some tail recursion optimization. But get SISC scheme for the full thing.

Craig Stuntz
+5  A: 

Erlang has a shared nothing model where each process has it's own garbage collector. Whether you consider that to be no concurrency or not it's up to you. But it sure scales very well as the number of processes goes up.

svenningsson
How does Erlang handle data passed from one process to another one? Is it replicated at each transfer?
Yoric
In general, yes, since Erlang supports seamless distribution. An implementation might share memory between processes under the hood but I don't think any of the existing implementations does.
svenningsson