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
True.. but it would have been a step too far from the existing language!
ReplyDeleteGood article anyway, thanks.
Hello Mr Viljamaa,
ReplyDeleteNice 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