on diamond and evolution

Rémi Forax forax at univ-mlv.fr
Fri Nov 6 05:49:16 PST 2009

Le 06/11/2009 12:31, Maurizio Cimadamore a écrit :
> Hi
> Following the recent discussions in this mailing list about the diamond
> implementation, I decided to spent some more time in order to figure
> out  exactly what it means, in term of language evolution, supporting
> the simple approach currently checked in the JDK 7 repository.
> Quick recap:
> *) Simple approach: infers the diamond type using the *only* the
> expected type (if available) - similar (if not identical) to
> *) Complex approach: infers the diamond type using a full inference
> round (arguments + return type) - +
> *) Full-complex approach: an hypothetical approach that is based upon
> complex (see above) - in addition, it throws the constraint about the
> expected type earlier in the inference process (precisely in,
> so that argument type inference cannot infer a type that, by being too
> specific, is incompatible with the expected type.
> As it was shown in [1] there is no subset relationship between simple
> and complex - that is the two inference routines simply yield different
> results - in this sense, the simple approach cannot be viewed as a
> proper subset of the complex approach.
> This is bad for evolution, as pointed out by Neal. My argument was that
> there existed a full-complex approach capable of subsuming both simple
> and complex at the same time - this would have allowed for further
> language extension (e.g. argument type inference) w/o breaking
> compatibility.
> After a more detailed analysis I found out that the full-complex
> approach, while feasible is not fully backward compatible with the
> simple approach. The full-complex works nicely when the attribution
> context has an expected type (because the type inferred for diamond is
> compatible with the types inferred by both approaches). However, when
> the attribution context is missing an expected type, things don't go as
> planned. Here's a simple example:
> class Foo<X>  {
>   Foo<X>(X x) {}
>   Foo<X>  get() { return this; }
> }
> Foo<Object>  = new Foo<>(1).get();
> With the simple approach this works just fine. The argument type is
> never considered during inference - because of that, diamond ends up
> inferring Object (the bound of X) for X. Calling get() on a Foo<Object>
> yields a Foo<Object>  which is compatible with the LHS type in the
> assignment.
> Now suppose that in some release>7 we enable the full-complex approach.
> What would happen to this particular example? When a type is to be
> inferred for Foo<>, both argument and expected type are considered. Here
> there's no expected type (the LHS type of the assignment is the expected
> type for the get() call) - so full-complex is roughly equivalent to
> existing Which (again) would yield a different type than the
> one returned by the simple approach - namely Foo<Integer>  instead of
> Foo<Object>. Now, calling get() on Foo<Integer>  would yield Foo<Integer>
> which is clearly incompatible with Foo<Object>. Btw: I'm not saying that
> accepting the above code is a must - an inference scheme can either
> accept (as simple) that or reject that (as complex); however, if we now
> choose a scheme that allows it, future releases will also have to cope
> with that, and we have seen clearly that even the full-complex approach
> cannot guarantee that.
> Bottom line: the full-complex approach doesn't represent a viable
> alternative for reconciling the diamond inference routine with the
> standard javac's method inference routine - as a result, the simple
> approach currently implemented in the JDK7 would represent an obstacle
> for future language extensions. In principle, it would be possible to
> limit the scope of the simple approach to those contexts that have an
> expected type, so that the simple approach would fail when no expected
> type is given. While this is clearly a forward compatible solution, we
> believe it would be unnecessarily restrictive and ultimately not worth
> pursuing it.
> Recalling from my earlier emails, the biggest disadvantage of the
> complex approach vs. simple is the following example:
> Foo<Object>  foo =  new  Foo<>(1);
> However I believe this can eventually be fixed by an inference overhaul
> on the lines of the full-complex approach, so that the argument type
> inference would take into account the expected return type (thus
> inferring Object instead of Integer). Actually, that's also the biggest
> advantage of the complex approach: any change that will positively
> affect javac's standard type-inference, will positively affect diamond
> as a side-effect.
> The next obvious step is to simply switch the diamond implementation in
> the jdk 7 repository, as we already have a working prototype (see [2]).
> Thanks to everyone for participating in the discussion and helping in
> making Java a better language.
> Maurizio
> [1] -
> http://mail.openjdk.java.net/pipermail/coin-dev/2009-August/002165.html
> [2] - http://cr.openjdk.java.net/~mcimadamore/6840638/webrev.1/

Hi Maurizio,
Correct me, If I'm wrong. You want to change the already existing 
inference algorithm
in order to be able to compile that code:

public static <T> List<T> list(T t) {

   public static void main(String[] args) {
     List<Object> l = list("foo");

And use the same algorithm for the diamond syntax.


More information about the coin-dev mailing list