Functional Java

With Java 8 the language got lambdas. This is a huge step towards allowing functional programming in Java and hence brings a fresh breeze. The language designers did not stop by simply providing lambdas but also extended the runtime API significantly to support lambdas and functional programming.

What are lambdas?

The Java Documentation for Lambda expressions gives a rather dry definition: “Lambda expressions let you express instances of single-method classes more compactly.”

Technically this is absolutely correct, but I think it does not convey the spirit of lambdas very well. Lambdas are Javas way to provide closures. It allows to define a function definition together with its environment. Here is an example:

import java.util.concurrent.Callable;
import java.util.function.Function;

public class ClosureTest {

    public static void main(String[] args) throws Exception {
        Callable<Function Integer>> createAdder = () -> {
            int[] sum= {0};
            return (Integer x) -> {
                sum[0]+=x;
                return sum[0];
            };
        };
        Function<Integer Integer> a1 = createAdder.call();
        Function<Integer Integer> a2 = createAdder.call();
        System.out.print(a1.apply(4) + " ");
        System.out.print(a2.apply(5) + " ");
        System.out.print(a1.apply(2) + " ");
        System.out.print(a1.apply(1) + " ");
        System.out.println(a2.apply(1));
    }

}

Output:

4 5 6 7 6

This creates an anonymous, higher order function stored in the variable createAdder() that returns an anonymous function that takes an integer and returns an integer. The returned function has a variable sum in its scope where it keeps the sum of all values with wich the function got called.

As you can see in the output, separate instances of the sum variable are created for every invocation of createAdder().

There is one wrinkle with these closures though. The restrictions of anonymous classes hold here too. You can only` access variables in the outer scope that are final or effectively final. A final integer would not work in the above example because it could not be updated. Hence the example uses a singleton array as a workaround. This is not recommended for production code.

Are lambdas just syntactic sugar?

At first glance, lambdas look like they are simply syntactic sugar for defining anonymous classes. However, there is a semantic and an operational difference.

The this keyword binds to the the class containing the lambda expression.

Operationally a lambda does not create a class, but a method on the containing class which is called via invokedynamic.

Why should I care?

Functional programming allows to write concise code, for example when providing a sort function:

l.sort((a,b) -> { return (a%2==b%2) ? a-b : (a%2)-(b%2); });

Or transforming and consuming collections:

l.stream().map((x) -> { return 2*x; }).forEach(System.out::println);

While all this was possible before Java 8 (via anonymous classes), having a concise syntax for it makes a big difference.