Battling Java's verbosity
Outside the Java community, Java is often regarded as an old and verbose language. Though I love writing Java code, I kind of have to agree with this. New features are implemented slowly and looked upon by the language designers with thorough suspicion. For example, support for multi-line strings has been tried multiple times before Java got official support[1]. If we are talking about verbosity, the Java language needs quite some characters to write a simple function. As I am specializing in functional programming in Java this year, I struggled a lot with this. Read along how I tackled this a little.
Don’t try to solve serious matters in the middle of the night
To understand my problem, let’s take an example of a earlier blog I wrote. A method that returns a curried function:
static Function<Meat, Function<Onion, Function<Spices, Function<Duration, Function<Duration, Void>>>>> createCurry() {
// implementation
}
If you read this kind of code, it takes a while before you understand it, even if you have experience in writing FP code. The simple fact that the Function interface consists of eight characters makes this code way to verbose if you want to use it multiple times. You just can’t read it by glance, because the method declaration is flooded with the use of the function interface. It would be nice if you could express the above method shorter without moving to another language that supports currying out of the box[2].
We are on a path of enlightenment
So I was thinking, if we write a simple function mathematically, we can write something like ƒ(x) = y
. If the ƒ character is enough for a school kid to understand this is a function, why should it not be enough for me? Having that idea, I started a Google search to check with characters are valid for Java classes. As it turned out, you can use almost any character, including most Unicode characters. Having this knowledge I quickly created following interface:
@FunctionalInterface
public interface ƒ<T, R> extends Function<T,R> { }
And indeed, it compiled without any problems. I started working with this interface, and it turned out to be a breeze. Above function could not only be rewritten shorter, it also shows its intention a lot more clearly:
static ƒ<Meat, ƒ<Onion, ƒ<Spices, ƒ<Duration, ƒ<Duration, Void>>>>> createCurry() {
// implementation
}
To infinity and beyond
After working some weeks with this new function interface I reviewed the situation. I used an unconventional interface name, but it actually made my code faster to write and easier to read. I never felt I created a learning curve at all, so I decided to expand this idea. I thought about this a while and came up with the following conventions:
-
The classes and interfaces that use this kind of verbosity shortener should consist of exactly one character.
-
To make it stick out of normal code, no ACSCII characters can be used.
-
The used character should have something in common with the shortened class or interface.
Instruction is good for a child; but example is worth more
At first, the next object I wanted to shorten was the Optional class. But I encountered a problem there. This class is defined as a final class so you can’t extend it[3]. This was kind of a bummer because initially I wanted to extend existing Java objects only, to provide a way to write 'better' native code. As this was no longer possible, I decided to go with some of the FP objects I created for my specialization. Here are some examples I used:
Option
The option object I created is similar to Java’s Optional class, though it’s implemenation makes it behave like a true monad. I choose the Ø
character as its representation. It consists of two parts, the letter O matches with the first letter of option/optional and a strike through to tell the user it can be on or off.
Either
The either object has two properties, a left and a right. You could argue it is a special case of an option, but instead of having the option to turn it on or off it is either one case or another. I choose the Ê
character to depict this. The E itself is the first letter of the word, where the ^ part gives away that something special is going on.
Result
Where the either object does not describe what the left and right property should be, most of the time you want a state where one property is 'right' where the other property is 'wrong'. Though you could use the either object for this goal, it’s better to create a specialized object to force its intent. Thus the result object is an enhanced either object, instead of left and right properties it has a value and an exception property. To portray this either-good-or-wrong case I chose the Œ
character. The left side of this symbol looks like a O that reminds us to the on state of the option object. The right side looks like an E, a character often used to illustrate exceptions.
Finish the work, otherwise an unfinished work will finish you
Now let’s bring this in practice one more time. Imagine a nonsense function that cast an object to a String. We can use a result object to indicate the casting was either successful or not. I think the difference speaks volumes:
Function<Object, Result<String>> castToString = o -> o instanceof String
? Result.success(o.toString())
: Result.failure(o.toString());
ƒ<Object, Œ<String>> castToString = o -> o instanceof String
? Œ.success(o.toString())
: Œ.failure(o.toString());
Though I used this technique to shorten my FP objects, I think it can be useful for whatever Java project. Especially wrapper objects are a good fit for this pattern. I am looking forward to see other developers use this approach as well!