Java 8 language spec flaw/bug
Davin McCall
davmac at bluej.org
Fri Aug 22 15:28:33 UTC 2014
On 22/08/14 15:23, Maurizio Cimadamore wrote:
>
> On 22/08/14 15:11, Davin McCall wrote:
>> The type arguments are those of Class - i.e. String and StringBuilder
>> (from Class<String> and Class<StringBuilder>, being the types of
>> String.class and StringBuilder.class respectively). These are used to
>> impose constraints on the type variable T (for the foo function). So
>> the constraints are: ‹String |<=| T› and ‹StringBuilder |<=| T›. Are
>> you saying that the paragraph I quoted does not apply, since 'T' is a
>> type variable and not a proper type? In that case should I apply instead:
> The paragraph applies, since it speaks about 'type'. An inference
> variable is a type. A type-variable is a type. String is a type. ?
> extends Something is _not_ a type.
> So, the constraints should be reduced as equality constraints. And
> that's the right thing to do - the results of type inference should be
> proper types - a wildcard is not an acceptable inference result (as,
> again, it's not a type...).
>
> Can think of a type T that is not a wildcard and yet it contains both
> String and StringBuilder?
No. But, if 'contains' constraints must always be reduced to 'equals'
constraints, then the problem is that there should be no 'contains'
constraint in the first place. In Java 7 the type of T could be inferred
to be a /capture/ of a wildcard expression, i.e. a capture of '? extends
...' where the wildcard contained both String and StringBuilder.
Look again at the method signatures, and the call that causes an error:
static <T> T foo(Class<T> clazz)
static <U> U ternary(boolean cond, U a, U b)
foo(ternary(true, String.class, StringBuilder.class));
(I've changed the name of the type variable of the 'ternary' method from
T to U, to avoid confusion).
Clearly U can be inferred to be 'Class<? extends ...>'. T can be
inferred to be a capture of the wildcard in U. It won't be true that
T=String, T=StringBuilder, String |<=| T, nor StringBuilder |<=| T, yet
clearly the type system is sound.
The constraints on T _should_ be:
String <: T
StringBuilder <: T
I'm reading through the spec again now to try and see where it's going
wrong.
Davin
More information about the lambda-dev
mailing list