Functional programming is the new hip programmer “must have”. And, while I’m generally skeptical of such trends, I do think that functional languages have a place in a good coder’s toolbox. I’d be wary of hiring a new developer who couldn’t answer general, non-language specific questions like, “What is a closure?”, “Tell me what the lambda function does and why would you use it?” Too many people introduce functional programming as a panacea, a cure-all answer to solve procedural complexity by changing the rules of the game. Functional is fashionable at the moment, and with fashion there is always a risk that you’ll look back at your photo album and regret the choices you made a few years back.
I’ve seen a number of clients take a purely functional approach to writing Java systems, some of them taking the constructs within Commons Collection and making systems compromised solely of Closures, Predicates, and Transformers. If they’ve ventured even further into the world of functional programming, they’ve likely found FunctionalJava or the sandbox-entrapped Commons Functor (last published in 2008). Closures, Predicates, and Transformers are useful, they are a very effective way to operate on collections in way that approximates real closures, and you should view them as a half-measure to hold you over until Java 8*. Some of the code I’ve seen it like slogging through someone’s ill-advised thought experiment – an exercise in functional obfuscation where the easy becomes difficult. In a quest for the ultimate application of lambda, ease of code comprehension was tossed by the wayside.
Over-application of Functional to Java
The issue with functional Java, or the over-application of lambda to Java, is one of complexity. Most programmers still live in a (mostly) procedural world. Your customers are describing procedures: procedures for selling insurance, procedures for computing cost, etc. Unless your employer (or customer) can afford to permanently employee developers who can bridge the gap between procedural requirements and functional implementation, you may want to consider using the most straightforward implementation possible. Even if this means using a (gasp!) for loop and doing something to each element of an array, if your problem doesn’t rise to a sufficient level of complexity, investing in the ceremony of functional Java programming is not worth the effort.
Part of the issue with functional Java programming is that the people who teach it. The writers, presenters, and developers who work on these libraries, rarely have enough time to develop meaningful examples. Instead of demonstrating the utility of functional patterns with a complex example worthy of strategies. We often illustrate the ideas of functional Java programming with an example that steps through an array of beans to print out a simple bean property. The first example uses a for loop and System.out.println, after an hour of introduction, the second version uses three or more closures: a Transformer, a Predicate, and a Closure. All in an effort to demonstrate the utility of functional Java programming.
What is difficult to convey after this hour is how unhelpful it is to your fellow developers to subject them to such an arcane series of custom interfaces and classes just to be able to print out a series of names. To this end, I need to identify better examples for functors in the Functors chapter. I need to find something that truly justifies the adoption of a functional approach in Java, and I need to add a section that speaks to the Faustian bargian you are making with the Java language if you decide to adopt a functional approach.
Caveat: If you really enjoy this, don’t use it
If functional makes sense for your problem domain, if you are going to be writing anything more than the most trivial functional code, you should use Scala, and (most importantly) draw a boundary between functional code and everything else. Whatever you do, don’t dive into functional programming in Java without first thinking through the consequences. I’ve seen these projects three years on, simple tasks like iterating through a list to print out bean properties is an ordeal that involves several anonymous inner classes. While it might feel clever and new at first, it is a proverbial “rabbit hole”, and after being exposed to some client code, I’m planning on adding strong cavets to everything I’ve ever written about functional programming in Java.
Telling a room full of programmers that functional programming is an alternative approach to programming: one that should be approached and understood on its own terms and appreciated as a tool for specific problems is one thing. Telling a room full of developers that it is the only way to develop is unwise. I’ve seen too many developers approach functional programming as a “cure all”, not fully understanding that while functional programming does have some benefits, there is a very heavy cost to writing functional code to do everything, this is especially true if the language you are using (Python, Perl, Java, Ruby) provides for a mixture of approaches. Sure, if you are using Scala or Clojure, go for it.
* Note: Everyone talks of Java 8 with certainty, but is there any certainty that Java 7 will make it out of the JCP? It seems like the ASF is serious about keeping Oracle honest. At the same time, you see companies like IBM diving into OpenJDK.