Java 8 language spec flaw/bug
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Fri Aug 22 13:13:12 UTC 2014
On 22/08/14 13:49, Davin McCall wrote:
> In the example I gave, the two 'contains' constraints are:
>
> T contains String
> T contains StringBuilder
>
> So while you are correct in saying that:
>
>> "is a type T contained in Integer?"
>>
>> The only possible answer is:
>>
>> "yes, only if T == Integer."
>
> ... the constraint is the wrong way around in your example, compared
> to the example I posted. It should rather be:
>
> "is the type Integer contained in T?"
Ah right - I inverted the terms - but same conclusion holds. If both
terms of a containment test are proper types (not wildcard
type-arguments), S <= T implies S == T.
Maurizio
>
> In this case the answer is
>
> "yes, if T is Integer, or a wildcard '? extends (some supertype of
> Integer)'.
No - only Integer, as a 'wildcard' won't be a 'type' - wildcards are
said to be type-arguments in the JLS lingo. They are not types. Which
means the paragraph you quoted only speaks about S and T being proper
types such as String, Integer.
>
>
>> Hence the spec derivation of the equality constraint.
>
> This derivation of an equality constraint is too strong, as I have
> shown; containment is not equality. I do however take your point
> about changing the contains constraint to a sub-type constraint being
> an incorrect solution. I suspect now that a full solution would
> require significant changes to the current wording of the spec.
Why is it 'too strong' ?
Maurizio
>
> Thanks,
>
> Davin
>
>
> On 22/08/14 10:23, Maurizio Cimadamore wrote:
>> 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:
>>
>> Object
>> ...
>> Number
>> ...
>> Integer
>> ...
>> nulltype
>>
>> 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.
>>
>> Maurizio
>>
>>
>> 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
mailing list