Lambda expressions

When getting started, functional programming is a huge topic. Getting involved can for sure be compared to when some years back imperative programmers started to use object oriented concepts. To get some starting point, lets take one concrete concept of functional programming and see how it works. I took the concept of the lambda expression as an example since this occurs in many articles recently, and I was always curious about the background.  The following explanations have been inspired by the book “Functional Programming for Java Developers” (https://www.amazon.com/Functional-Programming-Java-Developers-Concurrency/dp/1449311032), an excellent (and short – only 88 pages!) introduction into functional programming especially when you come from Java. The focus of the book is to show functional programming concepts using the Java language.

Lets assume we have some Java.awt.Button action listener defined which is executed when the button is pressed:

java.awt.Button but = new java.awt.Button(“Press me”);
but.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent e) {
                System.out.println(e);
   }
});

The ActionListener interface defines exactly one method which needs to be implemented and which is executed when the Button is pressed. Now, this code contains a lot of boilerplate code – all we apparently want to do is to execute System.out.println(e) when the button is pressed. Could this not be written shorter, like

java.awt.Button but = new java.awt.Button(“Press me”);
but.addActionListener(void (ActionEvent e) {
System.out.println(e);
   }
});

? In this (syntactically theoretical) example, we (means, the compiler) still have all necessary information available to produce the same code as above – we simply do not know anything about the name of the interface anymore (but the compiler could get it from the addActionListener() formal parameter list), and we also do not know that the method we need to call is actionPerformed() (but the compiler could get it from the interface defined in the addActionListener() formal parameters). Actually, we as developers do not need to know this – all we need to know is the parameters we need to pass to the method and the method body to execute. What we have created here is an anonymous function, which is also called a lambda expression in functional programming.

In the standard JAVA API, many such interfaces like ActionListener exist which are used to define simple callback functions. All these interfaces have in common that they only define a single method with a specific number of parameters (examples are AdjustmentListener, CaretListener, MouseWheelListener and quite some more!). Since this is a common pattern, such interfaces are also called Single Abstract Method (SAM) interfaces. Even without functional programming, we could improve those interfaces and make the Java API simpler by adding some level of abstraction. The only variable part of each SAM is the parameter list passed to the callback method. If we assume that each callback method has exactly one parameter, we could use a generic interface such as

public interface Callback {
    void callback(A a);
}

This interface can then be used everywhere a callback is necesssary – the example above would be written like

java.awt.Button but = new java.awt.Button(“Press me”);
but.addActionListener(new Callback<ActionEvent>() {
   public void callback(ActionEvent e) {
        System.out.println(e);
   }
});

This is already much easier than the existing java API approach, since we only need to remember one interface name (Callback) instead of dozens, and we only need to remember one method name (callback) instead of dozens different ones. The only thing we need to remember specifically is the type of the parameter – which is documented in the addActionListener’s API.

Anyway, there is still a lot of boilerplate code necessary in this example (new CallBack<ActionEvent>() { public void apply(ActionEvent e) …) even though the only variable part is the ActionEvent parameter. This again leads to the (theoretical) example given above, where the question was whether we can write something like

java.awt.Button but = new java.awt.Button(“Press me”);
but.addActionListener(void (ActionEvent e) {
System.out.println(e);
   }
});

This holds all necessary information, right? The compiler could reconstruct all the other parts (also called the the function wrapper) from this information, given that the interface is always called “Callable” and the method is allways called “callback()”. This is exactly what is called a lambda expression in JDK 8. The current syntax proposal looks a littlebit different than my theoretical example above, like

java.awt.Button but = new java.awt.Button(“Press me”);
but.addActionListener(
    #{ ActionEvent e -> System.out.println(e) }
  );

The parameters are on the left of the -> token, the function body is on the right. Obviously this approach needs syntactical extensions to the Java language, and this is what is currently discussed in Project lambda (https://openjdk.java.net/projects/lambda) and the corresponding JSR-335. However, the generic interface based approach from above can be implemented already today since it only requires Generics as language concept. There actually exists an open source project which follows this approach and which is available at https://functionaljava.org/. Among others, this project contains generic interfaces with up to eight parameters (remember – one assumption above was that the callback function takes only one parameter, and with more parameters additional interfaces are required with more generic parameters for the callback function).