Thursday, August 30, 2018

Why Java 10 local type inference is bad

For an overview of Java 10's local type inference see https://developer.oracle.com/java/jdk-10-local-variable-type-inference

The problem with local type inference is that the developer reading the code no longer has any idea of the shape of the object. We have reduced a developer's visibility to the name of the variable. For a developer to understand the type/shape/form/function they need to introspect back to wherever it was delivered or instantiated from.

In one of the examples given:

Map<String, List<String>> countryToCity = new HashMap<>();
// ...
for (Map.Entry<String, List<String>> citiesInCountry : countryToCity.entrySet()) {
  List<String> cities = citiesInCountry.getValue();
  // ...
}

We could rewrite this with var and reduce the repetition and boilerplate, like this:
var countryToCity = new HashMap<String, List<String>>();
// ...
for (var citiesInCountry : countryToCity.entrySet()) {
  var cities = citiesInCountry.getValue();
  // ...
}

It takes 3 introspective hops to determine the type of the cities var. If the value of the countryToCity has been provided from another method (which is extremely likely) then it will require 4 introspective hops. 

This is a massive diversion of the developer's focus.

Just because other languages have turned down this path does not mean that Java should.

I'm sure that there is a very (very) small set of problems for which local type inference is a worthwhile trade off. But in general, this is a VERY bad step for the Java language. It increases the cognitive load for the developer, and we already juggle way too many balls.

If you are using the syntax outlined above, do not expect an interview at any of my companies.