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?
|
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,
is basically sugar for
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:
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. |
|||||||||||
|
|
as I see it it is just syntactic sugar: to create a lambda you need to have a "functional interface" (only 1 method declared) to use the old Comparable for use in sorting: when you do
the compiler will probably translate that directly to
and compile that the method reference will likely do encompass the static method call in an instance method, so
will be translated to
this will be just the same as what happens with the variadic argument and it's translation to a array initializer edit: even if they don't decide to use anonymous classes or inner classes they could still decide to just use a custom classloader to create the objects that represent the lamba expressions either by extracting the code in the labmda to its own function or to another class and then passing the method name to a factory that will generate the appropriate code to call said function the lambda above will then be transformed to
and a new function will be added in
this can be done in 1.6 given enough work the OS project MinecraftForge has done something similar enough. The code for this can be viewed here |
|||||||||||||
|