Update on JEP-286 (Local Variable Type Inference)

Brian Goetz brian.goetz at oracle.com
Tue Dec 6 19:37:04 UTC 2016

[ Please do not respond directly; see below for instructions on 
providing feedback. ]

Over 2500 people participated in two rounds of surveys on Local Variable 
Type Inference (http://openjdk.java.net/jeps/286).

The results of the first round can be found at:

The results of the followup survey are here:

Responses to many of the issues raised in the survey are here:


Some analysis on readability, and goals, can be found here:

Some of these have been collected into a FAQ, here:

We'll be pushing an implementation soon that people can try out.


Overall, the responses were strongly in favor of the feature; 74% were 
strongly in favor, with another 12% mildly in favor.  10% thought it was 
a bad idea.

The written comments had more of a negative bias, but this shouldn't be 
surprising; people generally have more to say in disagreement than in 
agreement.  The positive comments were very positive; the negative 
comments were very negative.  So no matter what we do here, some people 
are going to be very disappointed.

When given a choice, the most popular syntax choice was "val and var", 
with "var only" as the second choice (the others were all obvious 
losers).  But when asked about how people felt about these choices, we 
saw a divergence; more people liked var/val, but more people hated it too.

While there were some passionate arguments against, the numbers speak 
loudly: this is a feature that most developers want.  (It is the most 
frequently repeated request of developers coming to Java from other 


The biggest category of negative comments regarded worries about 
readability (though most of these came from folks who have never used 
the feature; those who have used it in other languages were 
overwhelmingly positive).  We have always held out "Reading code is more 
important than writing code" as a core value of the language; plenty of 
folks took the opportunity to throw this seeming inconsistency in our 
face, on the assumption that this feature would inevitably lead to less 
readable code.

For example, code like the following strawman was offered by several 

      var x = y.getFoo()

as evidence of "see, its unreadable, you have no idea what 'x' is." The 
readability problem here, though, stems from the fact that 'x' is just a 
poorly chosen variable name.  Having a manifest type might make up for 
the programmer's laziness, but it would be better to just choose a good 
variable name in the first place.

While every situation may be different, we believe that, with judicious 
use of this feature in well-written code, readability is actually 
*enhanced*.  Consider a block of locals:

      UserModelHandle userDB = broker.findUserDB();
      List<User> users = db.getUsers();
      Map<User, Address> addressesByUser = db.getAddresses();

What is the most important thing on each line, the variable *name*, the 
variable *type*, or the initializing expression?  We claim it is the 
name that is most important -- because they describe the role of the 
variable *in the current program*.  And the variables names are not so 
easy to visually pick out from the above code -- they're stuck in the 
middle of each line, and at a different place on each line.

Ideally, we'd like for the most important thing to be front-and-center 
in the reader's view.  If we rewrite the above block with inferred types:

      var userDB = broker.findUserDB();
      var users = db.getUsers();
      var addressesByUser = db.getAddresses();

the true intent of this code pops out much more readily; the variable 
names are (almost) front and center.  The lack of manifest types is not 
an impediment, because we've chosen good variable names.

Another aspect in which this feature could improve readability is that 
users frequently construct complex nested and chained expressions, not 
because this is the most readable way to write the code, but because the 
overhead of declaring additional temporary variable seems burdensome. 
(We all do this.)  By reducing this overhead, implementation patterns 
will likely reequilibrate to a less artificially-condensed form, 
enhancing readability.


Many of the comments were not so much about the use of type inference, 
but about mutability -- a lot of people like the idea of reducing the 
ceremony associated with finality.  (And we like this idea too.)

Initially, we considered that perhaps inference would only apply to 
effectively final locals.  But after working with a prototype, we saw 
that this had an undesirable side-effect; mutable locals stick out badly:

     var immutableLocal = ...
     var anotherImmutableLocal = ...
     var alsoImmutable = ...
     LocalDateTime latestDateSeenSoFar = ...
     var thisOneDoesntChangeEither = ...

Fans of immutability might enjoy that mutability is punished in this 
way, but the irregularity was definitely annoying to those who tried 
this version.

Both of the paired versions (var/val, var/let) suffered from a similar 
problem.  Some readers found that var/val were so similar that they 
could mostly ignore the difference:

     var immutableLocal = ...
     var anotherImmutableLocal = ...
     var alsoImmutable = ...
     val latestDateSeenSoFar = ...
     var thisOneDoesntChangeEither = ...

whereas others found the small difference distracted them from the more 
important parts of the code.  Similarly, some found the var/let 
distinction distracting, whereas others liked it:

     var immutableLocal = ...
     var anotherImmutableLocal = ...
     var alsoImmutable = ...
     let latestDateSeenSoFar = ...
     var thisOneDoesntChangeEither = ...

Immutability is important, but in reality, local variables are the least 
important place where we need more help making things immutable.  Local 
variables are immune to data races; most locals are effectively final 
anyway.  Where we need more help in encouraging immutability is *fields* 
-- but applying type inference there would be foolish.

Further, the var/val distinction makes far more sense in other languages 
than in Java.  In Scala, for example, all variables -- locals and fields 
alike -- are declared with "val name : type", where you can omit the ": 
type" if you want inference.  So not only is mutability orthogonal to 
inference, but the power of the var/val distinction is greater because 
it is used in multiple contexts -- but we'd only use it for local 
variables, and only when their types are inferred.  (While the "name : 
type" syntax may be superior for this reason (and also because it moves 
the more important component forward), this ship sailed twenty years 
ago.)  So var/val is a feature that *looks* like it carries over 
cleanly, but in reality suffers greatly in translation.


I know this is the part people really care about :)   After considering 
the pros and cons at length, there appears to be an obvious winner -- 
var-only.  Reasons for this include:

  - While it was not the most popular choice in the survey, it was 
clearly the choice that the most people were OK with.  Many hated 
var/val; others hated var/let.  Almost no one hated var-only.

  - Experience with C# -- which has var only -- has shown that this is a 
reasonable solution in Java-like languages.  There is no groundswell of 
demand for "val" in C#.

  - The desire to reduce the ceremony of immutability is certainly 
well-taken, but in this case is pushing on the wrong end of the lever. 
Where we need help for immutability is with fields, not with locals. But 
var/val doesn't apply to fields, and it almost certainly never will.

  - If the incremental overhead of getting mutability control over that 
of type inference were zero, there might be a stronger case, but it was 
clear that many people found two different leading keywords to be a 
distraction that kept their eyes from quickly settling on the important 
stuff.  If variable names are more important than types, they're more 
important than mutability modifiers too.


To keep the signal-to-noise ratio to an acceptable level, we're asking 
people to provide (constructive) feedback through the following survey, 
whose results will be made public.


Thanks for all your feedback so far!

More information about the platform-jep-discuss mailing list