JSR 335 Lambda Specification, 0.9.1

Dan Smith daniel.smith at oracle.com
Mon Jan 6 16:44:22 PST 2014


An updated specification can be found here:

http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.1/

This contains some small tweaks that I'd like to include with the Proposed Final Draft; I'll simply update the language spec portion of the preview bundle I shared previously.

Other links
Diff: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.1-diff.html
One-page HTML: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.1.html
Downloadable zip: http://cr.openjdk.java.net/~dlsmith/jsr335-0.9.1.zip

Full change log, from the document:

> Introduction: Added brief discussions about exception transparency and speculative checking during overload resolution.
> 
> Method References: Removed the TypeName::m form of unbound method reference, which turned out to be unnecessary and introduced many complications.
> 
> Poly Expressions: Added a note clarifying that poly conditionals do not have to contain poly expressions.
> 
> Typing and Evaluation: Removed mentions of the TypeName::m method reference form. Allowed raw inner class types to be used in exact constructor references (because diamond inference cannot occur).
> 
> Overload Resolution: Eliminated unnecessary uses of the qualifier "poly" in discussions of conditional expressions.
> 
> Type Inference: Modified exception checking constraints so that they only exist for LambdaExpressions and MethodReferences (these constraints were previously generated for all other forms of expressions, and then trivially reduced to true).
> 
> Default Methods: Tweaked inheritance rule for interfaces so that a static/non-static clash would be properly detected.
> 
> Java Virtual Machine: Clarified that only 52.0 class files can allow InterfaceMethodrefs in method references of the kind invokeStatic andinvokeSpecial.

The EG may be particularly interested in the additional "Potential Future Enhancements" discussions, so let me reproduce them here:

> Special Exception Checking for Lambda Body Invocations
> 
> A checked exception thrown by a lambda body should be identified by the type system wherever the corresponding method is invoked. This is supported in a limited way by allowing functional interface methods to have throws clauses—then, naturally, the method invocation knows what exceptions may be thrown. It is also possible to use a type parameter of a functional interface in the throws clause, thus allowing a thrown exception type to be inferred (by, say, the invocation of a library method that accepts a lambda argument).
> 
> However, generics are not well-suited to the problem of representing the exceptions thrown by a block of code. In the common case (zero checked exceptions), an extra type parameter is a painful clerical burden (for example, Function<String, Number> becomes Function<String, Number, RuntimeException>). And in cases in which multiple exceptions are thrown, there is no way to provide a list of types as a type argument. Even with workarounds for these problems, it is difficult to write lambda-friendly library code that properly accounts for all the exception types thrown by the provided lambda bodies.
> 
> A more ambitious solution would be to special-case the treatment of lambdas in the compiler's exception checking logic, detecting the locations in which the checked exceptions of a lambda body may manifest themselves without relying on the throws clause of the functional interface. This would eliminate any clerical burden on programmers, while still providing strong exception checking; but it would require the compiler to perform advanced analysis techniques.
> 
> Speculative Type Checking During Overload Resolution
> 
> Implicitly-typed lambda expressions (that is, lambdas with parameters that do not declare their types) and inexact method references (that is, references to overloaded or generic methods) cannot be type-checked before their parameter types are known. These types are derived from the targeted functional interface type. In the case of a method invocation argument (e.g., m(x -> x.foo())), if the method being invoked is overloaded, there may be multiple possible target types, one for each overloaded method declaration.
> 
> The approach developed here is to ignore the lambda expression or method reference until after overload resolution decides on the method to be invoked—the lambda argument is not pertinent to applicability. Once overload resolution completes, the lambda body can be type-checked.
> 
> Another possible approach is to type-check the lambda body or method reference speculatively, once for each possible target type. This provides a more powerful disambiguation mechanism for overload resolution—the use of lambda parameters in the lambda body may clarify which parameter type was expected. However, there are a number of challenges: users must consider multiple possible typings when reading a block of code; program behavior depends on subtle type errors; worst-case computational complexity is exponential. And in some cases, it is still necessary to ignore lambda expressions during overload resolution, because the parameter types are inferred from the method invocation's own target type.

I know there are a variety of other features that didn't make the cut (we assembled a list back in July, which I'll reproduce for posterity here on the list sometime soon), but among topics that didn't yet have a discussion block, these seemed to me to be the areas that were the most fully pursued, and so deserving of special mention.

—Dan


More information about the lambda-spec-experts mailing list