support for 'var' in lambda parameters
maurizio.cimadamore at oracle.com
Wed Sep 27 12:07:01 UTC 2017
I've recently pushed a changeset  to enable use of 'var' in lambda
parameters. Below is some rationale on the implemented support.
In the current (e.g. JDK 9) grammar, we have two versions of lambdas:
*implicitly*- and *explicitly*-typed. Furthermore, an implicitly typed
lambda can come in two form (there's no terminology for it, so I'll make
up one): *compact* and *parenthesized*.
Let's see some examples:
x->x //implicit, compact
(x)->x //implicit, parenthesized
(String x)->x //explicit
So, the first question is - when is it ok to use `var`? There are two
1. allow `var` on all implicit lambdas
2. allow `var` only on implicit parenthesized lambdas
We concluded that (2) is the option that makes more sense - this allows
for a smooth verbosity curve (see below from most compact to least
(x)->x //added parens
(var x)->x //added 'var'
(String x)->x //ok, fully typed
Second question: we basically have now two kind of implicitly typed
parameters - those that omit type info in full (e.g. the formal decl is
just an identifier) and those using `var`. Can we mix and match between
(var x, y)->x+y
We have concluded that there's no need to mix and match. In fact, it is
more likely that one form of implicit parameter declaration will
supplant the other in the long run.
Third question: what about parameter modifiers such as `final` and/or
annotations? Historically, such modifiers were not allowed in implicit
lambda parameters (as those were just identifiers, and it poses several
parser challenges to e.g. allow annotations there); on the other hand,
local variables using `var` support both modifiers and annotations. We
concluded that, for consistency, we have to do the same when `var`
occurs in a lambda parameter.
Last question: can I mix implicit an explicit parameters?
(var x, String y)-> x + y
While that would be nice, it must be noted that this is a much deeper
change, with ramifications in overload selection, since implicit and
explicit lambdas are currently two disjoint sets, with very different
behavior w.r.t. overload resolution (see definitions of 'pertinent to
applicability' in JLS 220.127.116.11). For that reason, we won't go down
there now (but it's something worth considering in the future).
More information about the amber-dev