Language of the year: 2010
Testing Client Side Javascript with Jasmine and Node.js

A Bit of Heresy: Functional Languages are Overrated

Lets talk about problems. As professional software developers, we get paid to solve problems. Sometimes we do this by writing code. Sometimes we do this by finding creative ways to avoid writing code. In either case, it's important that the problem drives the solution, and not the other way around.

Enter: The Concurrency Problem. Moore's Law is starting to run out. We've all gotten very used to using hardware to solve scalability problems, and up until now, that's been a relatively easy thing to do. But chip manufacturers are starting to hit physical limits of transistor size and density. Now, the only way to scale up is to scale out by adding more cores, and that means concurrency. "But concurrent programming is hard!", they say. "And we have an army of semi-conscious Java developers in our company that wouldn't know a semaphore from a telegraph line! Oh noes! What will we do?"

The current fashionable solution to this problem are functional programming languages. They are the next big thing. Languages such as Scala, Clojure, Erlang, and Haskell are supposedly going to save us from the dread intermittent bugs and horrible deadlocks intrinsic in concurrent systems built with object oriented or procedural languages. The implication in this argument is that functional programming languages are more thread safe because (depending on the language) they either shy away from side effects or find ways to eliminate it completely.

Well, I'm sorry, but I'm just not buying it.

Don't get me wrong. Concurrent programming in a typical object oriented language is hard. Really hard. I've slogged through enough of it to learn to just avoid it unless you really, really need it. Especially when you're dealing with shared state. Michael Feathers once told me that he thought if threads had never been invented, and someone had proposed them at a conference today, they'd be laughed out of the building. He may have been kidding, but honestly, I would believe it.

My problem with the functional programming cure to this problem is that I haven't seen a cure yet that's better than the problem. Maybe it's me. Maybe my tiny Ben brain just can't comprehend the magic and majesty of OCaml, but every time I've tried to learn a new functional language, it's ended it disaster. First with Erlang, and then Haskell, I've now had two aborted attempts to understand the supposed cure to the concurrency problem. The languages are just too complex, too terse, and absolutely full of academic shitheaddery. I mean, seriously, what the hell.

If your concern with the death of Moore's law is that you won't be able to afford/find skilled programmers to scale your systems using multicore processors, these are not the droids you're looking for.

But even if you're got a bunch of really sharp developers on your team, I'm not sure this is the solution either. Message based architectures (especially asynchronous ones) are good, pretty easy to understand, and easy to test. Shared state in concurrent systems is a pain, and you shouldn't do that. Interprocess communication is relatively easy through various methods. Whether you're using an object oriented, pure functional, or hybrid language, these things are true.  And while it might be possible to ignore thread safety problems by just working in a purely functional language, I think you're just trading one kind of complexity for another. And if you're working in a hybrid language, what assurances do you have, really, that your system is really thread safe? Indeed, the risk compentation effect might give you a false sense of security, giving you a system that actually had more concurrency problems that one written in a "dangerous" language.

I think the downfall of some of these languages is that they get wrapped up in being "functional" rather than focusing on solving a particular class of problem. They abandon convention and common sense for complex type systems and functional purity. You can have an actor model architecture without using a functional programming language. You can avoid shared state in any modern language (even JavaScript). These things are not synonymous with functional programming.

I think the future of computing is people. Lots of people. Web applications, social networks, and millions (billions?) of mobile devices interacting over the net. I think the majority of these problems can be solved with multi-process, message passing architectures. In the end, a large scale system might wind up with one core for every 10 users. Maybe less. If multiple cores are the new gigahertz, I would not be the least surprised if computing gets that cheap. All it would have to do is follow the trend of the last 40 years, just along a different axis. Really, the only barrier to a process-oriented approach in that case would be memory, and that may not actually be a limitation at all.

So I think the cases where a functional programming language are really the best solution to the concurrency problem are, in fact, rather rare. It's worth noting that even after Twitter raised eyebrows by moving their backend processing from Ruby to Scala, they "reverted" to Java for some of the concurrent operations:

initially we had a number of actors inside the system...over time as we ran more and more system tests on it, we found that actors weren’t necessarily the ideal concurrency model for all parts of that system. Some parts of the concurrency model of that system are still actor based....but for other parts we’ve just gone back to a traditional Java threading model. The engineer working on that, John Kalucki, just found it was a little bit easier to test, a bit more predictable. 

So I need someone to explain this to me. The state of the art in functional languages scare me a lot more than intelligently-designed concurrent programming, but everyone is hopping on the bandwagon, so I feel I must be doing something wrong. So, in typical fashion, I've made a heretical claim in the hopes that someone will show me the light and prove me wrong. Because I seriously don't get it.


Feed You can follow this conversation by subscribing to the comment feed for this post.


"Shared state in concurrent systems is a pain, and you shouldn't do that."

If you need to share state, you can't magically work around this with a non-sharing solution. If you do not need to share state, it would be stupid to use a state-sharing solution.


Ben Rady


I agree. I have often found myself thinking that I need shared state...but when I later take the time to look at the problem a different way, it turns out that I don't. But sometimes you can't think of a different way.

My point is that the approach to dealing with shared state in functional languages usually to just to eliminate it completely from the language, which has other complexity ramifications. Eliminating it from your design is as effective a solution, and may actually be less complex.

Ben Rady

Colin and /b,

I haven't given Clojure a real try yet, but I'm still holding out hope that it will show me the way to FP enlightenment. Erlang and Haskell are just over my head (right now). Scala is OK (I'm using it almost every day now) but I still don't see how it's that much better than Groovy, Ruby, Python, or any other syntax sugary languages.

Also, Colin, +1 for actually trying to refute my central point (FP isn't that much better at concurrency) by pointing out Clojure's immutable data structures, which seem very nice and natural to me. A lot of the other comments were something like "[Language X] is awesome. You're just not trying hard enough to understand it."

Felix Pleșoianu

Now, I do think you are exaggerating. Erlang has the amazing quality that I can easily read code in it even though I don't actually know the language. Scala did make my brain hurt, but *I got it* (assert me != genius). And functional features in mainstream languages *are* useful. You know why? Because it's much easier to verify that the functional parts of your code are correct, and you can focus on the rest. Not to mention functional code is simply much more compact than imperative code in any language, which means less code to understand, audit and test.

That said, I don't like OCaml and Haskell either, but that's because of specific issues I have with each of them. And no, functional programming is no silver bullet, but that's because there are no silver bullets. Not because FP is inherently flawed.

If you want to give it a second chance, do what I did: start using FP features in mixed-paradigm languages. Ruby, Javascript, Python, Perl, whatever you're familiar with. You might have a pleasant surprise.


I think you have the wrong perspective on functional programming. Remember that functional programming has been around a lot longer than the concurrency problem, and the problem it originally tried to solve was "programming is hard," the same problem procedural languages try to solve. True, functional languages have never been as popular as procedural languages, but they have never been dead either, and the population of programmers using them has always had some pragmatic hackers without PhDs who genuinely thought they were the better languages.

So if being a disconnected, theoretical minded bearded professor is not a prerequisite for thinking that functional is best, what is? And why have procedural languages always been more popular?

I think more people would like functional programming if they only had more exposure to it, but the popularity of procedural languages (caused by job requirements, caused by popularity, loop on) has meant that to get paid you need to learn how to program procedurally. Once you know that, the motivation to spend the time required to learn functional programming is lessened drastically, often to the point where you would give up after a few hours of not getting anywhere. Learning /any/ language after your first is hard because of lacking motivation, though other procedural languages are often easier because they're similar to what you know, and you might be enticed by material benefits, such as satisfying a new job requirement.

Popularity aside, it seems to me that functional programming still isn't for everyone. There are people who've used functional programming for years professionally and still prefer procedural languages. Conversely, there are people who know procedural programming well but don't like it. I'm one of those. No matter how much procedural programming I've done, no matter how easy it is for me, no matter how good I am at "explaining" what I want procedurally, it still feels contrived, complex and interleaved compared to the simplicity and clarity of functional programs.

Anyway, this was the situation up until recently. Some liked procedural languages, some liked functional and sometimes these people had discussions and arguments about their relative merits. Procedural languages had the benefit of popularity, and functional programmers very often felt justified in their argumentation because they knew both paradigms well while the majority of procedural programmers had barely even heard of functional programming. The topic of these discussions were invariably which paradigm best solved the problem "programming is hard."

There are two points I'm trying to make here. One is that your claim that functional programming is hard is wrong. It might be hard for you specifically (or it might just be an artifact of inexperience with the paradigm), but for me it's easier than procedural programming, and we can both find other people supporting us. Biased as I am I suspect that if we somehow averaged out the difficulty across all programmers and all relevant problem domains, functional programming would be easier on average, but I cannot base that claim on anything but my own unfounded opinion, and neither can you do the opposite. We can only say that different people find them of different difficulty.

The second point I'm trying to make is that you should give functional programming another chance, but this time don't focus on the concurrency bit. As I said earlier, functional programming was not invented to deal with concurrency. It's very rich in techniques, new perspectives and mindbenders in many other problem domains as well, and in some ways learning the functional way is a lot like learning how to program for the first time. Focusing overly on "solving" concurrency is a lot like learning to program solely so you can write Half-Life 3 before Valve gets around to it; doomed to fail. Personally, I think the concurrency bit is a bit over-hyped and over-focused. There are many other good things about functional programming which deserve some attention beside that.

As for the actual benefits of functional programming regarding concurrency, I can only think of two that aren't reproducible in procedural languages, and both are related to controlled side-effects. One is that without side-effects you have immutability, and if your values are immutable you can share them among different threads as much as you like. Also, from the immutability you gain laziness, which can be exploited to perform evaluation of a single shared composite value in different threads with deterministic results without explicit coordination, or as an extreme, without even the knowledge of the programmer. The other benefit of controlled side-effects is that it becomes trivial to design the semantics and API for transactional memory compared to effects-by-default languages, as witnessed by the recent failure to bring STM to .NET, while Haskell has had STM for a couple of years now. STM itself is not a be-all end-all miracle drug appropriate for all cases, but it's pretty neat nonetheless.


I can understand the difficulty one can have trying to read terse functional programming. but as one of the previous commenters mentioned, its easier to grasp the terse syntax if you see the code you write in a functional program as telling the computer what to do instead of how to do it.

That being said after you have conquered that mole hill the code you write can still feel like 'write once, read never' code; And to solve that problem I would recommend reading the SICP ( book and or watching the lectures online lectures. That will take you from building big functional programs with map, zip, reduce methods everywhere; which is what makes your programs harder to read. and bring you to a place where your wrapping small collections of map, zip, reduce operations into what is essentially a DSL for the problem domain your working on.


For all the negative comments, I think that the author has a point: functional languages are overrated *as a solution to concurrency*.

That part - I think - is absolutely true, and the comment about trading one kind of complexity for another is spot on.

Evan Carroll

Seriously, this is one of the best rants I've seen in a long time. Kudos. I feel comforted knowing you failed at learning Haskell. I often wonder if PHP users feel as dumb as I do pursing RWH when they encounter a real programming language. Now, I must go back to mulling Haskell because ffs the shitbag in me demands I learn it.

Anony Mole

Functional languages, in their attempt to be terse, reduce or eliminate the "obviousness" of the code. If it takes 10 lines to do a sub-selection of a list using a set of filters, but the obviousness of the code is blatant then I think the developer has achieved the goal of making their code readable, self-evident and maintainable. If the same task could be done in 1 line of any of these functional languages, but that the follow-on developer who is tasked with maintaining this project is baffled by the brevity and character by character mental parsing that must take place to understand the intent of the code, then I believe that single line of functional programming has failed to accomplish its task.

Why make it so damn hard to understand? I would have hoped that languages would have gotten easier to understand - not harder.

Felix Pleșoianu

@Berengal There is no way to solve the "programming is hard" problem, it's a fundamental trait. All we can do is make ourselves into better programmers. And studying Lisp did make me a better programmer, even if I wouldn't use it for real-world tasks (not by choice anyway). Which may well be the single largest benefit of FP.

The comments to this entry are closed.