Is the introduction of the new lambda notation (see e.g. this article) in Java 8 going to require some kind of type inference?

If so, how will the new type system impact the Java language as a whole?


There's a fair bit of incorrect information in ratchet freak's answer and in its comment thread. I'll respond here in an answer, since a comment is too small. Also, since this an answer after all, I'll attempt to answer the original question too. (Note however that I am not an expert on type systems.)

First, the short answers to the original question are Yes and No. Yes, Java 8 will have considerably more type inference than Java 7, and No, there is not a "new" type system in Java 8, although there are some minor changes.

Java 8 will still be statically typed, and it will still have the dichotomy between classes and interfaces. There are no new types such as function types. The type of a lambda is essentially a "functional interface" which is an ordinary interface with a single abstract method.

Interfaces can now have code in the form of default methods, but the model of single-inheritance of classes and multiple inheritance of interfaces remains the same. There are some adjustments, of course, such as rules for method resolution in the presence of default methods, but the fundamentals are unchanged.

Any type that's inferred by type inference could be written out explicitly. To use ratchet freak's example,

Collections.<MyClass>sort(list, (a, b) -> { return a.order - b.order; });

is basically sugar for

    (Comparator<MyClass>)((MyClass a, MyClass b) -> { return a.order - b.order; }));

So sparkleshy's statement "type inference doesn't require any extension of the type system" is basically correct.

But to return to syntactic sugar, I'll repeat my statement that a lambda expression is not syntactic sugar for an anonymous inner class. Ratchet freak stated that a lambda expression is translated into an anonymous inner class instantiation, and Sparkleshy simply reasserted that a lambda is syntactic sugar for an anonymous inner class, but these statements are incorrect. They are probably based on outdated information. Early lambda implementations did implement lambdas this way, but things have changed.

Lambda expressions are semantically different from inner classes, and they are implemented differently from inner classes.

Lambda expressions are semantically different from inner classes in a couple ways. Evaluating a lambda expression need not create a new instance each time. They also have different capture semantics, for example, they capture this differently. In an inner class, this is the inner class instance, whereas in a lambda, this is the enclosing instance. Consider the following:

public class CaptureThis {
    void a(Runnable r) { r.run(); }

    void b() {
        a(new Runnable() { public void run() { System.out.println(this); }});
        a(() -> System.out.println(this));

    public String toString() { return "outer"; }

    public static void main(String[] args) { new CaptureThis().b(); }

In a recent JDK 8 lambda build (I used b69), the output will be something like the following:


Furthermore, lambda expressions are implemented completely differently from inner classes. If you compare the disassembled output, you'll see that the inner class code straightforwardly compiles to the creation and call to a constructor of CaptureThis$1, whereas the lambda expression compiles to an invokedynamic instruction that procures a Runnable through means unspecified. For a full explanation of how this works and why, see Brian Goetz' JavaOne 2012 talk Lambda: A Peek Under The Hood.

  • 2
    "they capture this differently. In an inner class, this is the inner class instance, whereas in a lambda, this is the enclosing instance. Consider the following:" still can be done with syntactic sugar by replacing all this with MyClass.this – ratchet freak Jan 7 '13 at 2:38
  • 4
    Everything that goes beyond assembler (and sometimes even that) is arguably syntactic sugar. But lambdas are not syntactic sugar for inner classes (any more). They serve a similar goal and have some similarities, but under the hood they are (observably) different. – Joachim Sauer Jan 7 '13 at 8:29
  • 1
    "Lambda expressions are semantically different from inner classes, and they are implemented differently from inner classes.": Thanks for the very good explanation (+1). What is still not clear to me is why have lambdas not been implemented as syntactic sugar for special anonymous classes or, in other words, what is the advantage of the extra complexity introduced by the new semantics? What problem does this solve that cannot be solved with anonymous inner classes? (But I still have to look at the link you posted, maybe I will find the answer there.) – Giorgio Jan 7 '13 at 10:26
  • 1
    @Joachim Sauer: I would consider syntactic sugar a new syntax for an existing semantics. When new semantics is introduced, I think you cannot speak about syntactic sugar. In this sense, I do not think that you can argue that everything beyond assembler is syntactic sugar. – Giorgio Jan 7 '13 at 10:27
  • 3
    @Giorgio: regarding why lambda isn't just syntactic sugar for anonymous inner classes, turns out there was a large discussion about this. This mail from Brian Goetz summarizes the decision: mail.openjdk.java.net/pipermail/lambda-dev/2011-August/… . TL;DR it leaves the door open for future evolution and we get better performance today. Goetz is actually answering a related question, Are lambdas objects? But if the answer is No or even Maybe that implies they cannot be sugar for inner classes. – Stuart Marks Jan 8 '13 at 1:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.