Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

How to avoid ruining your world with lambdas in Java 8

exploding-lambdas

The code and the beast

Amid the hysteria over the upcoming lambda expressions in Java 8, I started noticing how I haven’t really seen anything critical of Project Lambda in the many months since their introduction into the language was made public.

In reality, these already well-known lambdas are only spoken of positively–namely at conferences, in talks and generally around the interwebz–as a net benefit for Java. But are they really as wonderful as an awesome bacon-cheeseburger after a long day? And will you ask for more lambdas if you are required to use them in your daily work?

Let’s jump right in with some wonderful lambdas in our code right now:

public class RuinLambdas {
    public static void main(String[] args) {
        // Easy
        startDream(new Dream() {
            @Override public void dream() {
                // Dream boy, dream ...
            }
        });
 
        startDream(new AugmentedDream() {
            @Override public void dream(String dreamName) {
                // Dream boy, dream ...
            }
        });
 
        // Less easy
        startDream(() -> { /* Dream boy, dream ... */ });
 
        // And now kid ? ...
        startDream((dreamName) -> { /* Dream boy, dream ... */ });
 
        // Do you see which one it is directly by reading this ? ...
        startDream((dreamName, duration) -> { /* Dream boy, dream ... */ });
    }
 
    public static void startDream(Dream md) { md.dream(); }
 
    public static boolean startDream(AugmentedDream ad) {
        ad.dream("Ruin lambdas");
        return true;
    }
 
    public static boolean startDream(ThisIsNightmare hahaha) {
        hahaha.sufferMyKid("Hahaha you're going to hell", 2000);
        return false;
    }
}
 
interface Dream {
    void dream();
}
 
interface AugmentedDream {
    void dream(String dreamName);
}
 
interface ThisIsNightmare {
    void sufferMyKid(String dreamName, int duration);
}

So this is what we have:

  • Three interfaces for having nice dreams
  • A class with three nice methods for starting wonderful dreams
  • A main method that is a nightmare :)

What do we think/code/enjoy/understand?

Looking at the part that is commented is easy and readable. Here is what we can tell from that:

  • Looking at each method’s call we know directly which interface is used
  • Looking at each call we know which methods are implemented
  • The code is directly readable without interpretation
  • A developer that reads the code doesn’t need to know the code very well
  • A junior developer joining the team isn’t lost in the desert without water and cheeseburgers

And for the next lines using lambdas? Well, I won’t put more bullets because they will be the exact contradiction of previous points above.

Indeed, things are less readable by most human programmers that don’t know the code well. You could argue that one only has to look some lines below and I would have all my answers. Well, yes and no. In this particular case, yes, but life isn’t as easy as driving your bacon-wrapped Ferrari on an empty highway. But why is that?

Who could hate a lambda?

It’s tough being a lambda. I consider lambdas as human unreadable and hard to use. Let me ask you this: Do you have such simple projects with everything in one class? Do you have to maintain code that is months or weeks old? Code you haven’t even written yet?

In real life, you use Maven or Gradle-based projects for managing dependencies. Usually you use an IDE in order to develop your applications right? These are just two reasons it is not that easy to use lambdas.

Dealing with lambdas and dependency management

You don’t always have the source of the libraries you are using. When you have such a concise syntax like lambdas, you just have to navigate through the API documentation. When you don’t really know the library you’re using, you might need to spend some quiet hours understanding what is going on. And the syntax doesn’t help you figure out where and what you’re looking at.

Dealing with lambdas without an IDE

We have it good with the wonderful Ctrl + click feature of IDEs that bring you directly to the source code you’re looking for. Great, huh? But don’t take your IDE for granted, because if you don’t have one then you’ll need to go to your source server and modify a Java class with vi (vi? What’s that old boy? ;) ). Then maybe you’ll look at things differently.

In the days of “if I don’t know I Google it”, you can say that it won’t be that hard to identify what code does what. I think for experienced developers this is true. Because you know Java well, you can figure out where to look and get all ninja with writing bytecode directly in the JVM. But if you start on a new project and you’re stressing out because your boss totally sees that you can’t figure out why it’s still buggy after three weeks of trying to figure out why, then maybe things will be tougher.

The big paradox of lambdas is that they are so syntactically simple to write and so tough to understand if you’re not used to them. So if you have to quickly determine what the code is doing, the abstraction brought in by lambdas, even as it simplifies the Java syntax, will be hard to understand quickly and easily.

Lambdas, I still love you

Even if this article is about ruining the reputation of lambdas that are mostly sold as a revolution in Java 8, I still love them. Indeed if you’re used to them, they are really nice to use, mainly for quick treatments as displaying the value of each object in a list.

For complex algorithms maybe some developers will think of them as inappropriate. Java has never been a functional language, contrary to them lambdas now entering the heart of it. And in my humble opinion, things don’t have to be all and nothing…could we not keep lambdas where they are good, and rely on ultimately readable code for the rest? Context is important–you wouldn’t want to drive a cement truck to the supermarket for a bottle of milk, right?

I’m not sure if I’m the only one out there who is not 100% thrilled with the introduction of lambdas into Java 8, so leave your comments below if you agree/disagree.

Finally, I would like to leave you with this little lambda expression …

readers.stream()
               .filter(reader -> reader.isNinja())
               .forEach(reader -> reader.cheers());

Want to learn more about lambdas in Java 8? Check out Java 8 Revealed: Lambdas, Default Methods and Bulk Data Operations by Anton Arhipov, JRebel Product Manager at ZeroTurnaround.

Download the PDF version