Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"array initializer needs an explicit target-type" - why?

Following JEP 286: Local-Variable Type Inference description

I am wondering, what the reason is for introducing such a restriction, as:

Main.java:199: error: cannot infer type for local variable k      var k = { 1 , 2 };         ^    (array initializer needs an explicit target-type) 

So for me logically it should be:

var k = {1, 2}; // Infers int[] var l = {1, 2L, 3}; // Infers long[] 

Because Java compiler can already infer properly the type of an array:

void decide() {     arr(1, 2, 3);  // call  void arr(int ...arr)     arr(1, 2L, 3); // call  void arr(long ...arr) }  void arr(int ...arr) { }  void arr(long ...arr) { } 

So what is the impediment?

like image 978
Andremoniy Avatar asked Mar 06 '18 15:03

Andremoniy


1 Answers

Every time we improve the reach of type inference in Java, we get a spate of "but you could also infer this too, why don't you?" (Or sometimes, less politely.)

Some general observations on designing type inference schemes:

  • Inference schemes will always have limits; there are always cases at the margin where we cannot infer an answer, or end up inferring something surprising. The harder we try to infer everything, the more likely we will infer surprising things. This is not always the best tradeoff.
  • It's easy to cherry-pick examples of "but surely you can infer in this case." But if such cases are very similar to other cases that do not have an obvious answer, we've just moved the problem around -- "why does it work for X but not Y where X and Y are both Z?"
  • An inference scheme can always be made to handle incremental cases, but there is almost always collateral damage, either in the form of getting a worse result in other cases, increased instability (where seemingly unrelated changes can change the inferred type), or more complexity. You don't want to optimize just for number of cases you can infer; you want to optimize also for an educated user's ability to predict what will work and what will not. Drawing simpler lines (e.g., don't bother to try to infer the type of array initializers) often is a win here.
  • Given that there are always limits, its often better to choose a smaller but better-defined target, because that simplifies the user model. (See related questions on "why can't I use type inference for the return type of private methods. The answer is we could have done this, but the result would be a more complicated user model for small expressive benefit. We call this "poor return-on-complexity.")
like image 57
Brian Goetz Avatar answered Oct 01 '22 00:10

Brian Goetz