diamond operator and non-denotable types
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Tue Apr 13 06:44:06 PDT 2010
Paul Benedict wrote:
> I think the message is clear from the technical sense, but may I
> suggest an improvement? I do not believe most programmers would
> understand "denotable type" or "intersection type" and I would like to
> see an alternative wording.
>
The wording for 'denotable type' is likely to change; as Neal pointed
out, it's not correct in the technical sense either, as a wildcard type
would be equally invalid, while being denotable. I'll probably generate
a more general error message of the kind 'invalid type inferred for
Foo<>' and then leave to the 'where clause' the burden of going into the
gory details of that type.
On the other hand, the word 'intersection type' comes from the JLS. Note
that the 'where clause' section of an error message is intended to
provide additional specific information about types; in this respect
'intersection type' is the name of a type, pretty much like
'type-variable' and 'captured-type'. In any case, I think the current
wording is more expressive than just 'Number&Comparable<Number>'.
Maurizio
> Paul
>
> On Tue, Apr 13, 2010 at 7:49 AM, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>
>> Paul Benedict wrote:
>>
>>> Maurizio,
>>>
>>> Good response. Would you able to make the compiler's error diagnostic
>>> verbose enough to emit an error such as:
>>>
>>> "Construction with 'new Foo<>()' cannot determine type from
>>> "Number&Comparator". Please use normal construction syntax."
>>>
>>>
>> Hi Paul,
>> the error message that is currently generated is something like:
>>
>> TestX.java:4: cannot infer a denotable type argument for Foo<>;
>> Foo<?> f = new Foo<>() {};
>> ^
>> reason: type argument INT#1 inferred for Foo<> is not denotable
>> where INT#1 is an intersection type:
>> INT#1 extends Number,Comparator<Number>
>> 1 error
>>
>> The error message is taking advantage of the improved diagnostic support ---
>> the intersection type is explicitly described in a 'where' clause generated
>> by the compiler, listing all the upper bounds of the type.
>>
>> Maurizio
>>
>>
>>> This would help the user, like me, determine the possible types being
>>> expected.
>>>
>>> Paul
>>>
>>> On Mon, Apr 12, 2010 at 3:22 AM, Maurizio Cimadamore
>>> <maurizio.cimadamore at oracle.com> wrote:
>>>
>>>
>>>> Paul Benedict wrote:
>>>>
>>>>
>>>>>> The compiler
>>>>>> always erases an intersection type to the most appropriate type needed
>>>>>> in order to preserve the semantics of the program.
>>>>>>
>>>>>>
>>>>>>
>>>>> Maurizio,
>>>>>
>>>>> The diamond operator is supposed to be syntactic sugar, right? I don't
>>>>> think the class file is the problem here; let the compiler collapse
>>>>> the type as if you were not using the operator.
>>>>>
>>>>> Foo<?> f = new Foo<>();
>>>>>
>>>>> Just rewrite it like someone would write it in Java 5:
>>>>> Foo<?> f = new Foo<X>();
>>>>>
>>>>>
>>>>>
>>>> Hi Paul,
>>>> if the inference algorithm yields e.g. Foo<Number&Comparator<Number>>,
>>>> how
>>>> do you exactly go from this type to a type that the user would write?
>>>> You'd
>>>> have to choose between Number and Comparator<Number>, meaning that,
>>>> depending on your choice, the members of one class or the other will be
>>>> available for use --- which seems arbitrary, and not consistent with what
>>>> we
>>>> do with generic methods. Also consider that it's ot only about
>>>> intersection
>>>> types; there are also captured types which might be even harder to
>>>> 'simplify' (e.g. do you propose to use the upper or lower bound? What if
>>>> the
>>>> bound is itself non-denotable?)
>>>>
>>>> However, if you decide to keep Foo<Number&Comparator<Number>> as is, you
>>>> encounter a problem when you try to generate the classfile, in case the
>>>> diamond operator is of the kind:
>>>>
>>>> new Foo<>() {} //anon class
>>>>
>>>> in fact, this generates a class of the kind:
>>>>
>>>> class Anon$Foo extends Foo<Number&Comparator<Number>> { ... }
>>>>
>>>> Which is rather weird --- in fact, there's no way to represent this in
>>>> the
>>>> classfile without extending the classfile format and the Signature
>>>> attribute
>>>> format, which is way outside the scope of the coin project.
>>>>
>>>> Back to your question; is diamond syntactic sugar? On the one hand yes;
>>>> it
>>>> provides a way to avoid the need of manually specifying type parameters
>>>> on
>>>> class instantiation. However there's a subtle point here: the set of
>>>> types
>>>> returned by the inference algorithm is larger than the set of types that
>>>> can
>>>> be used in a correct Java programs. What do we do in such cases?
>>>>
>>>> In my original email I suggested to reject the program (because it has no
>>>> equivalent Java counterpart); on the other hand Neal would like to have
>>>> the
>>>> program accepted as long as this doesn't interfere with code generation;
>>>> this means only rejecting the case of anonymous inner class creation.
>>>>
>>>> Maurizio
>>>>
>>>>
>>>>
>>>>> Paul
>>>>>
>>>>>
>>>>>
>>>>
>>
More information about the coin-dev
mailing list