JEP 323: Local-Variable Syntax for Lambda Parameters

AuthorBrian Goetz
OwnerVicente Arturo Romero Zaldivar
Created2017/12/08 15:15
Updated2018/01/10 19:16
TypeFeature
StatusCandidate
Componentspecification / language
ScopeSE
Discussionamber dash dev at openjdk dot java dot net
EffortXS
DurationXS
Priority3
Reviewed byAlex Buckley
Issue8193259
Relates toJEP 286: Local-Variable Type Inference

Summary

Allow var to be used when declaring the formal parameters of implicitly typed lambda expressions.

Goals

Non-goals

Motivation

A lambda expression is either explicitly typed (all the types of its formal parameters are manifest) or implicitly typed (all the types of its formal parameters are inferred). A shorthand syntax is available for an implicitly typed lambda expression with a single formal parameter.

(int x, int y) -> x + y    // explicitly typed lambda
(x, y) -> x + y            // implicitly typed lambda; the types of x and y are inferred
x -> x.foo()               // unary implicitly typed lambda; the type of x is inferred

In Java SE 10, the type inference process that occurs for the formal parameters of an implicitly typed lambda expression was made available for local variables:

var x = new Foo();

For uniformity, we wish to allow the formal parameters of an implicitly typed lambda expression to be denoted with var as well:

(var x, var y) -> x + y    // implicitly typed lambda; the types of x and y are inferred

However, we do not wish to compromise the brevity of the shorthand syntax, so var x -> x.foo() will not be allowed.

Description

For formal parameters of implicitly typed lambda expressions, allow the reserved type name var to be used, so that:

(var x, var y) -> x + y

is equivalent to:

(x, y) -> x + y

An implicitly typed lambda expression must use var for all its formal parameters or for none of them. In addition, var is permitted only for the formal parameters of implicitly typed lambda expressions --- explicitly typed lambda expressions continue to specify manifest types for all their formal parameters, so it is not permitted for some formal parameters to have manifest types while others use var. The following examples are illegal:

(var x, y) -> x + y        // Cannot mix var and "no var" in implicitly typed lambda expression
(var x, int y) -> x + y    // Cannot mix var and manifest types in explicitly typed lambda expression

(In theory, it would be possible to have a lambda expression like the last line above, which is semi-explicitly typed (or semi-implicitly typed, depending on your point of view). However, it is outside the scope of this JEP because it deeply affects type inference and overload resolution. This is the main reason for keeping the restriction that a lambda expression must specify all manifest parameter types or none. We also want to enforce that the type inferred for a parameter of an implicitly typed lambda expression is the same whether var is used or not. We may return to the problem of partial inference in a future JEP.)

Alternatives

Continue declaring implicitly typed lambda expressions as in Java SE 8.

Risks and Assumptions

This JEP has no risk of source incompatibility when var is added before a parameter name in an implicitly typed lambda expression, because the type inferred for the parameter without var is the same as the type inferred with var.