support for 'var' in lambda parameters
maurizio.cimadamore at oracle.com
Thu Dec 21 21:00:26 UTC 2017
On 17/12/17 21:00, Maurizio Cimadamore wrote:
> the support for var in lambdas is only in the amber repository (lvti
> branch). For JDK 10 we have targeted the more mature part of the lvti
> But stay tuned, as we might have more news soon ;-)
And, as you might have noticed - here's the news:
> And thanks for trying out the feature - it is true that, if you want
> annotations, modifiers (such as final), you are currently restricted
> to use explicit parameter declaration, which in certain cases might be
> inconvenient if the types involved are big.
> On 17/12/17 06:48, Zheka Kozlov wrote:
>> I just downloaded the latest JDK (10-ea+36) and I cannot use `var` in
>> lambdas. Was this rejected? I now find this feature really useful
>> because I often want to write `(final var p) -> ...` instead of
>> `(final VeryLongTypeName p) -> ...`
>> 2017-09-27 19:47 GMT+07:00 Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com
>> <mailto:maurizio.cimadamore at oracle.com>>:
>> On 27/09/17 13:20, Zheka Kozlov wrote:
>>> Why should we allow `var` in lambda parameters? Who will ever
>>> need writing `(var x) -> x` instead of `x -> x`?
>> first of all, to clarify things, this is an experimental feature -
>> which is why it was left out from the JEP 286 integration into
>> Secondly, JEP 286 is not just about 'var' in local variable
>> declaration (although I agree that's the most frequent use case).
>> You can also use 'var' in other places too, such as for loops and
>> try-with-resources. From an uniformity perspective, one could
>> argue that lambda parameters are another place where the 'var'
>> treatment could be applied.
>> As you point out, lambdas do provide a more succint version to
>> declare implicit parameters - but in a language that is evolving
>> to use 'var' in more places (pattern matching will likely use
>> 'var' for pattern bindings), I think that, from a pedagogical
>> question at least, it makes sense to allow 'var' in all places
>> where you want to declare a variable but you don't care about
>> giving it an explicit type.
>>> 2017-09-27 19:07 GMT+07:00 Maurizio Cimadamore
>>> <maurizio.cimadamore at oracle.com
>>> <mailto:maurizio.cimadamore at oracle.com>>:
>>> 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
>>> 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 choices here:
>>> 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 compact):
>>> (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 these e.g.
>>> (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 184.108.40.206). 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