Thursday, February 25, 2016

How to Name Lamdas

This post is basically about how to make provocative claims. Lamdas in Java 8 are anonymous functions by definition. They can not be named, whatsoever. However, it is possible to make a lamda behave as if it was named by using a delegation technique.

The mechanism with which lamdas are integrated within the object oriented model in java 8 is the functional interface. The same mechanism is also used to support method references. Via the form of a Functional Interface, lamdas and method references have become first class citizens. You can pass them into methods as parameters to write Java code with a functional programming flavor. In this setting, you are frequently in need of a costum toString method for a variety of reasons that include but are not limited to:
  • logging
  • reporting (e.g., test reports with Jenkins or IDE pluggins)
  • debugging
However, the toString is the default Object implementation that is not informative. Consider for instance the following class.

When you run this code, you will see the following string printed in the console:
apackage.AClass$$Lambda$1/989110044@2f2c9b19
Clearly this string is not informative at all. In this post, I show how to attach meaningful toString implementations to Functional Interfaces and therefore to lamdas and method references. The code is available on github.

Implementation

A well known motto says that any problem in computer science can be solved by an additional level of indirection. The same idea applies to the NamedLamda interface shown below.

NamedLamda is a Functional Interface because it has a single abstract method. As of Java 8, interfaces can have implemented methods which are defined with the default identifier. The abstract method apply takes a String input and returns a String. Therefore, NamedLamda is compatible with any lamda that is comnpatible with Function<String,String>. When the namedWith method is called, an instance of an annonymous Class implementing NameLamda is returned. That annonymous class defines a custom toString and its apply method implementation delegates to the original lamda. Take a look at how NamedLamda is exercised in NamedLamdaTest.