Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Lambdas and Closures

Tags:

I hear lambdas are coming soon to a Java near you (J8). I found an example of what they will look like on some blog:

SoccerService soccerService = (teamA, teamB) -> {
    SoccerResult result = null;
    if (teamA == teamB) {
        result = SoccerResult.DRAW;
    }
    else if(teamA < teamB) {
        result = SoccerResult.LOST;
    }
    else {
        result = SoccerResult.WON;
    }

    return result;
};

So right off the bat:

  • Where are teamA and teamB typed? Or aren't they (like some weird form of generics)?
  • Is a lambda a type of closure, or is it the other way around?
  • What benefits will this give me over a typical anonymous function?
like image 443
IAmYourFaja Avatar asked Jul 09 '12 22:07

IAmYourFaja


People also ask

Are lambdas same as closures?

Lambda functions may be implemented as closures, but they are not closures themselves. This really depends on the context in which you use your application and the environment. When you are creating a lambda function that uses non-local variables, it must be implemented as a closure.

Are there closures in Java?

Java does not have closures. if you then do something like pass f to a function, scope is the scope of where it was defined.

What is Closures in Java programming?

Closures are the inline-function valued expressions which means that they are the class functions with bounded variables. Closures can be passed to another function as a parameter. A closure gives us access to the outer function from an inner function.

Does Java 8 support closures?

In effect, java doesn't have closures at all. One may not notice the difference unless they have used real closures in a language that actually supports them.


2 Answers

The Lambda expression is just syntactic sugar to implement a target interface, this means that you will be implementing a particular method in the interface through a lambda expression. The compiler can infer the types of the parameters in the interface and that's why you do not need to explicitly define them in the lambda expression.

For instance:

Comparator<String> c = (s1, s2) -> s1.compareToIgnoreCase(s2);

In this expression, the lambda expression evidently implements a Comparator of strings, therefore, this implies the lambda expression is syntactic sugar for implementing compare(String, String).

Thus, the compiler can safely assume the type of s1 and s2 is String.

Your target interface type provides all the information the compiler needs to determine what are the actual types of the lambda parameters.

Briant Goetz, Java Language Architect at Oracle Corportion has published a couple of articles of the work in progress in JDK 8 Lambdas. I believe the answers to your questions are there:

  • State of Lambda.
  • State of Lambda Libraries Edition.
  • Translation of Lambda Expressions
  • JVMLS 2012: Implementing Lambda Expressions in Java

This second article explains how the lambda expressions are implemented at the bytecode level and may help you delve into the details of your second question.

like image 52
Edwin Dalorzo Avatar answered Sep 22 '22 08:09

Edwin Dalorzo


See this page for a full version of that example (however, the relevant parts are shown below).

The types are inferred from the SoccerService interface and SoccerResult enum, not shown in your snippet:

enum SoccerResult{
    WON, LOST, DRAW
}

interface SoccerService {
    SoccerResult getSoccerResult(Integer teamA, Integer teamB);
}

The benefit (of lambdas versus standard anonymous classes) is just reduced verbosity:

(x, y) => x + y

versus something like:

new Adder()
{
  public int add(int x, int y)
  {
    return x + y;
  }
}

For the difference between a closure and a lambda, see this question.

like image 28
DNA Avatar answered Sep 20 '22 08:09

DNA