Functional Java

Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

I have just finished reading a neat little book about functional programming for Java developers by Dean Wampler. The book is only sixty pages long so it’s a really fast reading. This is a book for Java programmers and others working in the object oriented paradigm that haven’t read about or done any functional programming before. If that fits you then this book may be a good choice to read. Otherwise, I recommend that you seek more advanced and in-depth books in the subject instead. But this text will not be a review of the book. I will instead comment on the use of the functional structure and its paradigm in languages like Java that is not designed for it.

Functional programming in Java

I definitely believe that you will improve as a programmer if you study other paradigms than the one you mainly work under. If you normally use an object oriented language you will improve your skills if you learn functional programming; your code will improve if you implement side effect free functions and uses immutable data structures as much as possible. The code will be more understandable and testable using those techniques.

What you shouldn’t do is to copy the solutions, idioms and patterns on a more detailed level. Functional code is based a lot on the list abstraction and high order functions like filter and map, and you create increasingly higher abstractions describing your problem domain by combining these basic building blocks. This is not is easy to copy in imperative languages that do not have closures and not treating functions as first class citizens. The above mentioned book has a code example that very nicely shows this:

public class FunctionCombinatorTest {
    @Test
    public void higherOrderFunctionCombinatorExample() {
        List<Integer> listI = list(1, list(2, list(3, list(4, list(5, list(6, emptyList()))))));
        Integer sum = listI.filter(new Function1<Integer, Boolean>() {
            public Boolean apply(Integer i) { return I % 2 == 0; };
        })
        .map(new Function1<Integer, Integer>() {
            public Integer apply(Integer i) { return I * 2; };
        })
        .foldLeft(0, new Function2<Integer, Integer, Integer>() {
            public Integer apply(Integer seed, Integer item) { return seed + item; };
        });
        assertEquals(new Integer(24), sum);
    }
}

The list function is a factory method creating an immutable list object and the resulting list contains 6 elements. The code applies the functions filter, map and foldLeft in sequence to calculate the sum of all doubled even numbers stored in the collection. Using the functional structures; the immutable list and the functional interfaces Function1 and Function2 together with the high order functions, you get some benefits. But the above code is horrible; something quite simple has been implemented really complex. The problem has a low essential complexity but the solution has a very high accidental complexity. The anonymous class construct is very verbose and is not suited to use in this manner. I would argue that you should avoid this, and if you are working in Java you should stick to the imperative style when implementing algorithms like the above.

Other functional languages on the JVM

But, today you also have a second option that is even better; you can use one of the new languages on the JVM, for example Clojure or Scala, to implement certain parts of the application using functional structures. The below code is from a simple clojure module that includes the function calculate with a straightforward implementation of the aboveJava code (but it returns the result instead of asserting it).


(ns functional_clojure.core
  (:gen-class
    :name functional_clojure.core.ClojureFunctionalCombinator
    :methods [[calculate [] int]]))

  (defn -calculate [this]
    (let [values '(1 2 3 4 5 6)
         (reduce + 0
                 (map #(* 2 %)
                      (filter even? values)))))

The method first declares the collection of the six values and then applies the three functions sequentially on it until the sum has been calculated. The namespace (ns) declaration at the top contains the gen-class macro which is used to generate a Java class named ClojureFunctionalCombinator, and which also includes the method calculate. The class can be used in Java as the code below shows.

@Test
public void testClojure() {
    ClojureFunctionalCombinator fc = new ClojureFunctionalCombinator();
    assertEquals(24, fc.calculate());
}

Summary

If you would like to get the benefits from the functional paradigm, and if you feel you have the need for it, I recommend you to take a deeper look at Clojure. One of Clojures main strengths is its software transactional memory model which simplifies multithreaded implementations quite a lot. But Clojure is also really easy to integrate and use from Java code and vice versa. You compile the clojure code and pack it into a jar which you then include into the java project; that’s it. Because of this there isn’t really much that should stop you from start developing small library functions in Clojure in your current project as a way of exploring the language and the functional paradigm.

Leave a Reply

Your email address will not be published. Required fields are marked *