Functional vs “Java” Style
Stephan Schmidt started it with his third point:
Do not use loops for list operations. Learning from functional languages, looping isn’t the best way to work on collections. Suppose we want to filter a list of persons to those who can drink beer. The loop versions looks like:
List<Person> beerDrinkers = new ArrayList<Person>();
for (Person p: persons) {
if (p.getAge() > 16) {
beerDrinkers.add(p);
}
}This can – even in Java – be rewritten to a more a functional programming style. For example using Google collections filter:
Predicate<HasAge> canDrinkBeer = new Predicate<HasAge>() {
public boolean apply(HasAge hasAge) {
return hasAge.getAge() > 16;
}
};
List<Person> beerDrinkers = filter(persons, canDrinkBeer);
Then Cedric Beust countered with:
No loops
Java is not very well suited to a functional style, so I think the first example is more readable than the second one that uses Predicates. I’m guessing most Java programmers would agree, even those that are comfortable with comprehensions and closures and especially those that aren’t.
I guess this means I’m not “most Java programmers”. Although I find the verbosity of the anonymous Predicate in Stephan’s code lamentable, aside from that I think the functional style is far superior. And I don’t believe it should be seen as in any way at odds with “normal” Java style. There’s no magic here: it’s just a straightforward anonymous class and filtering is a very simple concept to understand. Conceptually it is no harder than the explicit loop: in fact it is easier as you know the higher purpose as soon as you see “filter”.
The higher level of abstraction is the key to its superiority. Every non-trivial Java project will include many instances of searching, filtering, folding and so on of collections. Repeating this most basic of logic time after time fills the code with mechanical details that hide its true purpose. Why not get those details right once (in a library) and then never have to see them again?
In fact, once you embrace this style, things get even better. Not only can you reuse basic operations like filtering, you can also:
- Compose these operations to form even higher-level manipulations.
- Build up a reusable set of functors (Predicates, Transforms, etc) instead of using anonymous classes.
The latter point is important, as it allows you to remove an even more damaging sort of repetition — that of your project’s domain-specific logic. Reduce Stephan’s example to:
and it is clearly superior.
Really, I think it is a shame to see Java programmers hesitant to use this style. The ideas may come from the functional world, but there is nothing but basic Java code at work here. The abstractions are both simple and powerful, which to me is the very definition of elegance.
This entry was posted on Friday, August 21st, 2009 at 12:24 am and is filed under Java, Opinion, Technology. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

August 21st, 2009 at 3:01 am
Excellently said. You might also look at Functional Java. I think this is my first ever non-argumentative blog comment.
August 21st, 2009 at 3:26 am
Hi Ricky,
Thanks for the comment, although it sounds like I’ll need to be more controversial next time :). I have seen Functional Java which looks interesting. I am somewhat wary of the reimplementation of basic collections — have you found this an issue when working with other Java libraries? I’d have to actually try it before I could pass any meaningful judgement.
I actually do really need to look into the alternatives as Pulse currently uses a home-grown library. It was born before there was a decent alternative (particularly one which made use of generics), but I’m sure we’d be better off switching to something more complete now.
August 21st, 2009 at 5:30 am
Yes a good post indeed. I already tried to express that recently, after 4 years of doing just that in our team.
You do emphasize what’s important: over time a growing set of functors can be reused and composed together (boolean operations etc) as a plumbing kit. We used Apache Commons Collections Predicate, Closure and Transformer a lot (with Java 1.4) and very quickly all the team loved it, without even knowing for a long time that this was called functional style. And the benefits talked for themselves: much higher reuse, less LOC, no side effect, trivial unit testing, flexibility to configure the application at assembly time…
Whenever I mention functional style everybody immediately speaks about Scala, F# or another sexy language, whereas what’s really important is the style in itself (paradigm), not the syntactic sugar.
August 25th, 2009 at 5:08 pm
It looks like Google engineers haven’t reached consensus about a functional style in Java. Josh Bloch http://gafter.blogspot.com/2007/12/what-flavor-of-closures.html?showComment=1197631980000#c8863950537789037629 and Cedric Beust http://beust.com/weblog/archives/000517.html are against the functional style in Java, while the authors of Google Collections http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?com/google/common/collect/Iterables.html promote and support it.
August 26th, 2009 at 12:15 am
It really is just a matter of personal preference and not of better readability. The simple fact that the code contains a lot of class and function definition keywords like new, return, public, boolean plus additional parentheses makes this harder to read IMHO. I am sure that there are useful applications of this but stating that the one is “better” than the other is nothing more than an opinion.
Frank
September 4th, 2009 at 4:21 am
Best to switch to Scala. People like Joshua Bloch have condemned Java to stagnation.
September 20th, 2009 at 10:22 pm
It is true that Java is not well suited to a functional style, but it does raise the question, just what “style” is it suited to?
It is far more suited to a “functional style” than not, as your code provides anecdotal evidence for (the case generalises).
I wish we, as an industry, did away with this Java nonsense and moved on.