[concurrency-interest] Are functional languages so much better at concurrency?
Osvaldo Pinali Doederlein
osvaldo at visionnaire.com.br
Fri Feb 9 07:26:17 EST 2007
Brian Goetz escreveu:
>> Joel, from joelonsoftware, claimed twice that functional languages are
>> excellent for developing concurrent apps.
> The side-effect-free property is indeed nice and makes a lot of
> concurrency problems just go away. Programming in this style (heavy use
> of immutable objects, sharing as little state as possible) in stateful
> languages like Java also makes concurrency easier.
> So, the question is, are functional languages better or worse for
> ordinary programming? My innate confidence in the efficient market
> hypothesis tells me there's a reason that languages like C and C++ and
> Java and Perl and Python have been so successful; they are well-suited
> to the problems most programmers need to solve and map well to how most
> programmers think. Functional languages, despite their obvious
> mathematical advantages, don't seem to have caught on in mainstream
Yes, I think the trick (like in many other cases) is combining the
advantages of both models. Haskell is already a great innovation with
its Modans system, which accomodates things that actually require
side-effects like I/O in a ghetto that doesn't spoil the rest of the
language. But they still try to be purely functional for all normal
In Java, I try to keep code close to functional when possible. See
page 40, "/The final modifier and refactoring: towards functional-style
Java/". Even inside a single method I try to avoid gratuitous side
effects - a mutable for loop counter is fine, but updating a local
variable in a on-loop code path just doesn't make sense for me, just
create a new variable and your code is even more readable (see article).
Updating attributes of "worker" objects - things used temporarily (and
locally) to perform some task that demand more state than it's
comfortable to pass around by parameters through several methods - is
okay too, just don't share the objects. But for shared data that gets
held by static variables and accessible (even potentially) for multiple
threads, I try to use only immutable objects. This requires some extra
work and patience - like when a coworker complains "where are the
f****** setters in your POJOs, I wanna update'em in the GUI!". But they
payoff is great, I can build complex, highly scalable server apps where
you can hardly find a synchronized keyword or a concurrency bug.
Scalability is great and easy, double the CPUs and the throughput
doubles, of course if there are no other issues like concurrent,
pessimist database updates.
Interestingly, I think that the Java EE programming model helps here.
Your are admonished to not use threads and synchronization, and while
you can still do that with care, the whole framework is geared towards
share-nothing code and transactions. Now, transactions are great for
expensive JTA resources like database and JMS connections, but we still
don't have STM with or without JTA support, so the EE model doesn't work
for lean-and-mean shared stuff, such as configuration data, singleton
instances, caches of fixed domain tables (those critical enough so that
the overhead of an ORM tool is too big, even with L2 caching), "worker"
objects that are more expensive to build than to execute, etc. Well,
just make all that stuff immutable and your're ready to go: scalable,
efficient AND Java EE-compatible, no locking required.
Great example if Java API design: java.util.regex. My app has a little
expression language used in decision trees, so I can just bring the
whole trees to memory and precompile the expressions; any regular
expressions are Pattern.compile()'d, everything is put in a shared cache
(beautiful name for static variables), and because all objects are
immutable including the compiled Patterns, I can use them from multiple
transactions/threads without synchronization. It's easy, fast, and
Bad example of API design: java.text. I cannot use the same trick for
SimpleDateFormat and the likes, because these objects are neither
immutable, nor thread-safe. I'm forced to create new formatter objects
every time, and recreating these objects is expensive (I measured it)
even though they seem to make some effort to reuse the precompiled state
from an internal cache (if your're making all that effort, why not just
working harder on the precompiled state so it can be immutable?). Add
this to the parse() methods that only accept a String (Pattern at least,
accepts CharSequence; ideally, both should accept readers/writers or
streams) and these classes are totally useless for performance-critical
code... So I end up writing my own date and number parsing/formatting
methods for often-used formats.
Osvaldo Pinali Doederlein Visionnaire Informática S/A
osvaldo at visionnaire.com.br http://www.visionnaire.com.br
Arquiteto de Tecnologia +55 (41) 337-1000 #223
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Concurrency-interest