Monday, March 17, 2014

A Question about Java 8 Lambda Expressions

Java 8 is out. Its big new feature is "Lambda Expressions".  I've done some reading on them to prepare myself having used 'closures' in other languages.

The best way to learn is to ask questions, and I have one about Lambdas. Why can't the syntax be simpler?  The best way to learn is to ask questions, so here we go.

I will discuss below a slightly modified version of a Java 8 lambda-expression example from  http://www.oracle.com/technetwork/articles/java/lambda-1984522.html.  I've modified parts of the example to make it shorter, to keep the focus on the syntax.


1. The Question

To create a lambda-expression you must first DECLARE an interface that describes it (unless someone else has done that already).  In the linked-to example it was called HelloService. I renamed it to HelloInterface, to be clear it is a Java "interface", which is one of the key concepts to understand about lambda expressions.  It is defined like this inside the class Hello:

public class Hello 
{
   interface HelloInterface 
   {  String hello (String fname, String lname);
   }
...
}

This 'target-interface' of a lambda-expression needs to be a "Functional Interface", meaning it must define  a single abstract method.

That is the point of lambdas, to make it unnecessary to write a whole new class when you only need a single method. But because Java is statically typed, you still need to declare the interface of the lambda to indicate its argument- and result -types.

To CREATE a lambda that conforms to the interface above you write a lambda-expression like this:
   
 HelloInterface myLambda
 =  (String fname, String lname) 
     -> { String s = "Hello " + fname + " " + lname; 
          return s; 
        };

You can see the expression after the  '='  looks kind of like a function, without a name.  Which is what Lambdas are!

After  creating the lambda above you USE it like this:

 String s2 = myLambda.hello ("Will", "Smith");
     

Now comes my question. The "functional interface" needed to create a lambda has a single method. Then WHY do we need to give a NAME to that ONLY method?  Wouldn't it be easier to write:

   interface HelloInterface 
   {  String (String fname, String lname);
   }
   ...

  String s = myLambda ("Joe", "Doe");


2. The Answer,  kind of 

From http://download.java.net/jdk8/docs/api/java/lang/FunctionalInterface.html  we can read: "... Conceptually, a functional interface has exactly one abstract method. Since default methods do have an implementation, they are not abstract".

To understand the above you must know about another new Java 8 feature:  Default Methods. These are methods you can define for an interface. You couldn't do that before Java 8. If a class implementing such an interface does not provide its own implementation for a default method, it gets the implementation defined for the interface. You can read more about default methods here.

THEREFORE it is NOT the case that 'functional interfaces' can have only a single method. It is the case they must have one abstract method.  But in addition they can also have some default methods. Therefore when "interacting" with a lambda, we must specify which of its methods we are calling.

BUT:  It is the case that for every lambda-expression there must a single abstract method, declared in its functional interface. Therefore we could say: IF you want to call the single abstract method  (which is the case most often) THEN it is unnecessary to specify which method you are calling. If such a rule was adopted, we could call it with:

  String s = myLambda ("Joe", "Doe");

Maybe there's a reason why that couldn't be done in Java 8, but I don't know it at the moment. But that's OK, I'm learning new things daily.


 © 2014 Panu Viljamaa. All rights reserved 

2 comments:

  1. True.. but it would have been a step too far from the existing language!
    Good article anyway, thanks.

    ReplyDelete
  2. Hello Mr Viljamaa,

    Nice blog! I am editor at Java Code Geeks (www.javacodegeeks.com). We have the JCG program (see www.javacodegeeks.com/join-us/jcg/), that I think you’d be perfect for.

    If you’re interested, send me an email to eleftheria[dot]kiourtzoglou[at]javacodegeeks[dot]com and we can discuss further.

    Best regards,
    Eleftheria Kiourtzoglou

    ReplyDelete