The Curious Failure of Functional Programming for Parallel Applications
by Malte Skarupke
Long title, but it is interesting how functional programming has mostly failed to gain traction in parallel and concurrent applications. People think that functional programming should become more popular as we do more and more parallel programming, but that doesn’t happen. As an example this blog post made the rounds recently which has this quote in it:
However, the key to multicore programming is controlling mutation. This is why functional languages have been steadily gaining ground in concurrency and parallelism.
Which I would disagree with. Not the controlling mutation part, but the steadily gaining ground part. Let’s look at a few examples:
I work in video games and the most parallel thing we do is programming shaders. And there isn’t a single popular functional shader programming language. (In fact I’m not sure if there are any at all, but I’d bet that someone probably wrote one as a hobby project) Same thing for general purpose GPU compute languages.
When looking at areas other than gaming the most common parallel programming is probably web server programming and the big data software that came out of that. But looking for example at Google App Engine’s supported languages you find Java, Python, PHP and Go. Amazon AWS has SDKs for several more languages but again none of them are functional. (you can of course run anything you want on Amazon EC2, but their SDKs for the provided services are a good indicator for what languages people have used in the past) Since everyone supports Java, you could run Scala or Clojure and I’m sure people do, but again it is curious that the most parallel application in this field, Hadoop, is written in Java.
So why doesn’t functional programming take off? In general functional programming doesn’t take off because it’s weird. But functional programming fans have often claimed that people would overcome that weirdness in order to get the easier parallelism that functional programming offers. So why didn’t that come true?
It turns out that you if you really want to scale, you have to design for parallelism from the ground up. And if you have done that, it doesn’t really matter which language you use. Shader programming would not benefit from being functional because you simply don’t have to think about controlling mutation. Same thing for service oriented architectures and map reduce.
Yes, functional programming makes concurrency easier because some problems simply can’t happen, but it turned out that Amdahl’s law is the bigger problem. And you’re going to run into that even in functional languages. It doesn’t matter how well you control your mutable state: If your design requires that step A has to happen in order to do step B, you can’t parallelize that. Once you have a design that pushes Amdahl’s law back far enough where you can ignore it, it doesn’t matter much which language you choose to implement that design.