Local Variable Type Inference - prototype

Remi Forax forax at univ-mlv.fr
Thu Mar 10 22:13:19 UTC 2016

```Hi Stuart,

----- Mail original -----
> De: "Stuart Marks" <stuart.marks at oracle.com>
> À: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>, platform-jep-discuss at openjdk.java.net
> Envoyé: Jeudi 10 Mars 2016 22:56:43
> Objet: Re: Local Variable Type Inference - prototype
>
> Hi Maurizio,
>
> Nice work! I gave this a spin using the new JEP 269 Convenience Collection
> Factories. [3] The following examples transliterated from the old "collection
> literals" proposal [4] worked quite nicely:
>
>      // List<Integer>
>      var piDigits = List.of(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 9);
>
>      // Set<Integer>
>      var primes = Set.of(2, 7, 31, 127, 8191, 131071, 524287);
>
>      // Map<Integer, String>
>      static var platonicSolids = Map.of(
>          4,   "tetrahedron",
>          6,   "cube",
>          8,   "octahedron",
>          12,  "dodecahedron",
>          20,  "icosahedron");
>
>      // List<List<Integer>>
>      var pascalsTriangle =
>          List.of(List.of(1),
>                  List.of(1, 1),
>                  List.of(1, 2, 1),
>                  List.of(1, 3, 3, 1),
>                  List.of(1, 4, 6, 4, 1));
>
> The following example, however, failed:
>
>      // List<Number>
>      var numbers = List.of(2, 2.718281828);
>
>      error: cannot infer type for local variable numbers
>      var numbers = List.of(2, 2.718281828);
>      (inferred type is non denotable)
>
> The old Coin proposal suggested that this was an edge case that would require
> a
> type witness. Rephrasing that example in terms of the collections factories,
> it
> would be
>
>      List<Number> numbers = List.<Number>of(2, 2.718281828);
>
> However, type inference had improved enough already by JDK 8 that this works:
>
>      List<Number> numbers = List.of(2, 2.718281828);
>
> But trying to push this to
>
>      var numbers = List.of(2, 2.718281828);
>
> doesn't work. This is a rather special case. The "obvious" choice is
> List<Number>, but as Brian mentioned in his "Reader Mailbag" message [5,
> Q#10],
> that the inferred type is actually likely to be much more complicated, hence
> the
> "non denotable" message. In this case requiring an explicit type is probably
> warranted anyway.

The issue is that the inferred type is something like:
Number & Comparable<? extends Number & Comparable<?> & Serailizable> & Serializable
because
Integer implements Comparable<Integer> and
Double implements Comparable<Double>

so types like Number or Comparable<?> are valid substitute of T with no obvious most specific types, here.

An interesting question for the future is to see if inference can be improved by making union types denotable like in Ceylon [1] (or in TypeScript, or the next version of Scala),
something like:
List<Integer|Double> numbers = ...

>
> So... ship it! :-)
>
> s'marks

Rémi

[1] http://ceylon-lang.org/documentation/1.0/spec/html/typesystem.html#uniontypes

>
> [3] http://openjdk.java.net/jeps/269
>
> [4] http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/001193.html
>
> [5]
> http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000039.html
>
>
> On 3/10/16 6:48 AM, Maurizio Cimadamore wrote:
> > Hi,
> > I've pushed the first iteration of the local variable type inference
> > prototype
> > in the sandbox repository[1]. For those willing and brave enough to
> > experiment,
> > the branch name is "JEP-286-branch". We are also working to get some
> > binary snapshots out of the door and hope to have an update on that soon.
> >
> > This first iteration supports the 'var-only' syntax style:
> >
> > var s = "Hello!";
> >
> > That is, the type of 's' is inferred from the initializer, and no special
> > assumption is made about mutability.
> >
> > Please share your experience with the prototype. For comments on this
> > feature
> > please refer to the survey[2] that Brian posted few days ago.
> >
> > Maurizio
> >
> > [1] - http://cr.openjdk.java.net/~chegar/docs/sandbox.html
> > [2] -
> > http://mail.openjdk.java.net/pipermail/platform-jep-discuss/2016-March/000037.html
>
```