Re: Java 8 language spec flaw/bug
timo.kinnunen at gmail.com
Fri Aug 22 10:48:24 UTC 2014
This reminds me of the JEP draft: Improved variance for generic classes and interfaces at http://openjdk.java.net/jeps/8043488
It even says this in the part about type-checking which seems directly relevant:
“Enhanced subtyping: When subtyping encounters two parameterizations of the same class type, it performs a pairwise comparison of the type arguments using type argument containment. The intuition is that a wildcard can "contain" a range of types, while a type can only "contain" itself. By enhancing this relation, we might allow one type to "contain" another if the corresponding type parameter is variant and an appropriate subtyping relationship holds between the two types.
With this approach, it might also be useful to define type equality such that a wildcard-parameterized type is considered the same as that type with the wildcards removed.”
This regression would then be a concrete incentive towards that JEP.
Perhaps one of the “rules governing appropriate usage of type variables” would be to
have a Class<T> be treated as Class<? extends T>, similarly to the proposed rules for Iterator<Number> as-if Iterator<? extends Number> and Predicate<String> as-if Predicate<? super String>?
Have a nice day,
Sent from Windows Mail
From: Maurizio Cimadamore
Sent: Friday, August 22, 2014 12:23
To: Brian Goetz, Davin McCall, lambda-dev at openjdk.java.net
I believe the spec is correct as is - note that '<=' denotes a
'type-containment' constraint, not a subtyping constraint. To think
about type-containment it is sometimes useful think about types in terms
of 'ranges' over simple hierarchies of types (we can let alone
interfaces, which only makes everything more complex in this regard). If
you think about an imaginary line that goes from Object to 'nulltype' -
you will have the following:
Now, ordinary type (such as Number, Integer) can be thought as 'points'
in this imaginary line. On the other hand, wildcard type-arguments are
ranges or intervals on this line. For instance, the wildcard '? extends
Number' is the interval that goes from Number down to nulltype.
Type-containment answers a very simple question: is the interval denoted
by one type contained into the interval denoted by another type?
Now, using the above metaphore, it is easy to see that if you have a
point-like type in the RHS of a containment-test:
"is a type T contained in Integer?"
The only possible answer is:
"yes, only if T == Integer."
Hence the spec derivation of the equality constraint.
I hope this helps.
On 21/08/14 17:46, Brian Goetz wrote:
> This turns a 'contains' constraint directly into an 'equals' constraint,
> which is precisely what causes the problem. I can see no justification
> for this. It should instead imply a sub-type constraint, that is, it
> should reduce to ‹S |<:| T›. At this point the problem goes away,
> without - as far as I can see - having any negative impact on the
> enhanced type inference that Java 8 provides. Instead of getting two
> conflicting equality constraints for the T in the Foo example above
> (T=String and T=StringBuilder), we would get two subtype constraints
> (String <: T and StringBuilder <: T), which from a theoretical
> perspective is perfectly correct.
More information about the lambda-dev