I am a software engineer at Google on the Android project and the creator of the Java testing framework TestNG. When I'm not updating this weblog with various software-related posts or speaking at conferences, I am busy snowboarding, playing squash, tennis, golf or volleyball or scuba diving. Cedric is a DZone MVB and is not an employee of DZone and has posted 90 posts at DZone. You can read more from them at their website. View Full User Profile

Clojure, Concurrency and Silver Bullets

08.20.2010
| 5393 views |
  • submit to reddit

Rob Martin has become a fan of Clojure recently. Nothing wrong with that, Clojure has a lot going for it and if you’ve never had a chance to write code in Lisp, it’s probably the best way to begin these days.

But then, Rob gets a little bit too emotional and he starts drawing all kinds of dangerous conclusions. Such as this one:

Why is functional programming important? Because Moore’s law has started to falter.

It’s not the first time that functional programming gets advocated as the heroic technology that will rescue us from buggy multithreaded code *and* that it will allow our programs to magically scale along with the multiple cores that computers have these days. Concurrency problems? Just pick a functional programming language — any language — and suddenly, your code is multithread safe and it will automatically scale.

I find this simplification a bit disappointing coming from technologists, but I really read this at least once a week these days.

If you’ve ever written multi-threaded code, the thought of eight, sixteen, thirty-two, or even more processors running your program should fill you with dread. Writing multi-threaded code correctly is hard! But why is it so hard? Because it is hard to manage the state of variables when more than one CPU has access to them.

First, a nit: when you write multi-threaded code, two processors shouldn’t scare you more than four. Either your code is multi-threaded safe or it’s not. The only thing that changes when you run it on multiple processors is that you are more likely to find bugs when you throw more processors at it.

I’ll agree with Rob on the fact that managing the state of variables with more than one CPU is hard, but come on, it’s still not rocket science. As I write this, hundreds of thousands of lines written in C, C++, C#, Java and who knows what other non functional programming languages are running concurrently, and they are doing just fine.

Java has shown amazing powers of adaptation over the years, and when it comes to concurrency, people like Brian Goetz and Doug Lea and libraries such as java.util.concurrent don’t get the recognition they deserve. Java is also the living proof that you don’t need concurrency support at the language level to be effective, libraries can do just fine.

That kind of code is admittedly harder to write than straight imperative programming, but can anyone who’s looked at Clojure’s STM API (atoms, agents, ref) or Scala and Erlang’s actors say that writing code with these paradigms is that much easier?

To make matter worse, these new paradigms come at a cost that’s very often glossed over by their own advocates. When people tell you that “Actors are a share nothing architecture”, they are lying to you. You are sharing a great deal with actors, just in more subtle ways that your mind needs to be very aware of. You have the illusion of automatic multi thread safety but you pay the price by having to wrap your head around a fully asynchronous model. It’s not easy. And when you have two actors A and B that are sending messages to an actor C, aren’t they sharing the state of C?

Stephan Schmidt attacked this subject not long ago. Read his post and don’t miss the comments, they are very enlightening as well. My take away from that discussion is that if there is a silver bullet to concurrency programming, Actors are not it.

Actually, it’s pretty clear to me that there is no silver bullet, and Alex Payne seems to agree. In this post, Alex sends a very powerful message of compromise and inclusion. Blocking or non-blocking I/O? Select or events? Java locking or Actors? Agents or refs?

Anyone who tells you that only one of these approaches works and the others don’t is trying to sell you something.

To quote Alex:

In fact, taking a hybrid approach to concurrency seems to be the way forward if the academy is any indication.

Strive to learn new languages, technologies, paradigms, just don’t fall in love with them.

From http://beust.com/weblog/2010/08/19/clojure-concurrency-and-silver-bullets

Published at DZone with permission of Cedric Beust, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Peter Veentjer replied on Fri, 2010/08/20 - 4:32am

What Clojure does is raising the abstraction level so users don't need to deal with lower concurrency abstractions all the time.

But under the hood Clojure itself afaik is relying heavily on the concurrency abstractions that are part of Java. So I certainly don't think Clojure is going to replace them, it only prevents dealing with them all the time.

The same goes for the Akka project which also relies heavily on the lower level concurrency abstractions (and of course my own project Multiverse).

Peter Veentjer
Multiverse: Software Transactional Memory for Java
http://multiverse.codehaus.org

Honey Monster replied on Fri, 2010/08/20 - 5:25am

when you write multi-threaded code, two processors shouldn’t scare you more than four. Either your code is multi-threaded safe or it’s not. The only thing that changes when you run it on multiple processors is that you are more likely to find bugs when you throw more processors at it.

Uhm, the present model for multi-threaded code in Java only allows a very coarse-grained threading. Hence the work on project lambda. The challenge is two-fold: Getting synchronization right *and* allow for massive multi-threading. This is where a more fine-grained model is called for. Sure you can handcraft the use of 2-4 threads for an application and split the work between them. But given 40 threads, can you really keep them all busy and thus use the processor optimally?

This is where the the fine-grained models are called for. But with finer granularity also comes increased headache with communicating and synchronizing state. The functional paradigm already works best with immutable structures. As it so happens, immutable structures are also really well suited in a massive multi-threaded environment where you want to avoid synching as much as possible.

Do we need new programming languages for that? I believe so. The imperative OO languages can be built out somewhat to accommodate FP like constructs to some degree. And this will go a long way to help train developers for the new paradigm. But in the end I believe that mainsteam development will migrate to something more functional than the current mainstream languages.

Arek Stryjski replied on Fri, 2010/08/20 - 7:43am

I was never in love with Java Thread and I will not cry if one day it will be gone from my life.
I hope it will disappear as old collections, AWT, or old events did, and Java will still be around in few years time.

Endre Varga replied on Sat, 2010/08/21 - 5:27am

Most of my job involves doing discrete event simulations, which means that I do a lot of message-passing, asynchronous style programming. And let me tell you: IT SUCKS

Does anyone remember why programmers INVENTED blocking calls? Coz they are easier, that's why.

Peter Bliznak replied on Mon, 2010/08/23 - 5:21pm

"That kind of code is admittedly harder to write than straight
imperative programming, but can anyone who’s looked at Clojure’s STM API
 (atoms, agents, ref) or Scala and Erlang’s actors say that writing code
 with these paradigms is that much easier?"

 

Well if you dont see how much easier it is then ... then it is eye exam time for you.

 

BTW what is it YOU are trying to sell? Last few comments you made you are dancing around same thing.

Cedric Beust replied on Mon, 2010/08/23 - 11:48pm in response to: Honey Monster

Ulfe: Java allows you to be arbitrarily coarse grained in your locking, I'm not sure how more fine grained you can be..

 

 

Cedric Beust replied on Mon, 2010/08/23 - 11:51pm in response to: Peter Bliznak

Anonymous: I am not selling *anything*, which is what differentiates me from a lot of technology advocates, who very often praise technologies that they have a vested interest in, either intellectual or financial

I have the utmost respect for Rich Hickey and Martin Odersky, but certainly you need to read their article in praise of their respective inventions with a bit of a critical eye.

 

 

Peter Bliznak replied on Tue, 2010/08/24 - 7:49pm in response to: Cedric Beust

Critical eye..ok then. I am sure you are true proffesional guy but have you ever worked on system which required heavy threading?....I do have most respect for guys who wrote java.concurrent api but even if you master it  and use it in your project you still wouldn't sign it off on your watch because deadlock will get you - unless you are maverick - in 6 months. Now try to use for same purpose actor model  - have you? - result is simple that you can say it will work and put your prof reputation on it. That is all I am saying. Is scala or erlang silver bullet? I dont know but easpecaii erlang has top rating in that category.

King Sam replied on Fri, 2012/02/24 - 10:15am

I wonder about the comment that Java doesn’t have concurrency support at the language level. The concurrency libraries couldn’t be as robust as they are without a clearly specified memory model and language-level support for threads.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.