cast at call site problem

Remi Forax forax at univ-mlv.fr
Wed Apr 3 07:04:14 PDT 2013


On 04/03/2013 03:18 PM, Maurizio Cimadamore wrote:
> On 03/04/13 12:36, Remi Forax wrote:
>> On 04/03/2013 12:54 PM, Maurizio Cimadamore wrote:
>>> On 03/04/13 11:38, Anna Kozlova wrote:
>>>> What are reasons behind that then?
>>> Cast conversion rules are very complex - and defining an inference
>>> process that would satisfy them would make inference a lot more 
>>> complex.
>>> It would also increase the surface of backward incompatibilities.
>> At the same time, this means that
>>     A a = foo();
>> can compile but
>>     A a = (A)foo();
>> can not compile which is really a bad semantics for a mainstream 
>> language.
>>
>> I don't think there is a choice here,
>> even if we don't do inference on cast now,
>> the history shows that we will add this rule in the next release.
>> So better to that now because we are already introducing backward
>> compatibility hazard with the introduction of the complex algorithm that
>> to introduce backward compat. issue twice (between 7 and 8 and
>> betweeen 8 and 9).
> While I sympathize with your argument, I also think that we are a bit 
> too close to the finish line to be making this kind of changes.

yes, but as I said, we will do that in 9 anyway.

> Note that a solution would have to deal with cases like:
>
> (A) cond ? foo() : foo()

yes, but it's not different from
A a = cond ? foo(): foo()

>
> and also with stuff like
>
> (UnrelatedInterface) foo()

The rules that are complex are the one between U and V when you have,
   U u = (V) ...
and the implementation of javac was very wrong before you fix them.

Back-propagating the type of V when doing the inference will not make
these rules more complex, because you still require that the inferred 
return type
of foo() to be compatible with V before trying to resolve the cast from 
V to U.

So the issue is more backward compatibility, because without inference
the return type of foo() can be compatible with V but with inference it 
can be incompatible.

Given that we already introduce incompatibilities, I think it's better 
to do that once and not twice.

>
> In other words, it's not just matter of pushing the context down to 
> the innermost level; we need to define some strategy in order to say 
> as to whether the type in the cast should be considered as a 'target' 
> or not. And, typically, there's no way to answer this question without 
> looking at the expression itself.

BTW there is already a case where the cast is used to provide
type information, it's when you use MethodHandle.invoke/invokeExact.


>
> Maurizio

Rémi

>
>
>>> Maurizio
>> Rémi
>>
>>>> -----Original Message-----
>>>> From: lambda-dev-bounces at openjdk.java.net
>>>> [mailto:lambda-dev-bounces at openjdk.java.net] On Behalf Of Maurizio
>>>> Cimadamore
>>>> Sent: Wednesday, April 03, 2013 11:54 AM
>>>> To: Anna Kozlova
>>>> Cc: lambda-dev at openjdk.java.net
>>>> Subject: Re: cast at call site problem
>>>>
>>>> On 01/04/13 15:59, Anna Kozlova wrote:
>>>>> The call foo(Collections.emptySet()); is much more clean I suppose. I
>>>>> just wonder why the redundant cast leads to compilation error.
>>>> As per spec EDR, a cast does not pass its type down to the 
>>>> expression being
>>>> converted. This means that the call to emptySet is typed with an 
>>>> Object
>>>> target; hence the error. If you remove the cast, the right target 
>>>> is used.
>>>>
>>>> Maurizio
>>>>> Thanks
>>>>>
>>>>>
>>>>> From: paulus.benedictus at gmail.com 
>>>>> [mailto:paulus.benedictus at gmail.com]
>>>>> On Behalf Of Paul Benedict
>>>>> Sent: Monday, April 01, 2013 4:51 PM
>>>>> To: Anna Kozlova
>>>>> Cc: lambda-dev at openjdk.java.net
>>>>> Subject: Re: cast at call site problem
>>>>>
>>>>>
>>>>> I believe you want to write this:
>>>>> foo(Collections.<String>emptySet());
>>>>>
>>>>>
>>>>> On Mon, Apr 1, 2013 at 9:48 AM, Anna Kozlova
>>>>> <Anna.Kozlova at jetbrains.com>
>>>>> wrote:
>>>>>
>>>>> Hello all,
>>>>>
>>>>> Is it a bug or is it an intentional behavior:
>>>>> This code compiles
>>>>> {code}
>>>>>         void foo(Set<String> s) {}
>>>>>
>>>>>         void bar() {
>>>>>             foo(Collections.emptySet());
>>>>>         }
>>>>> {code}
>>>>>
>>>>> but this code doesn't:
>>>>> {code}
>>>>>         void foo(Set<String> s) {}
>>>>>
>>>>>         void bar() {
>>>>> foo((Set<String>)Collections.emptySet());
>>>>>         }
>>>>> {code}
>>>>>
>>>>> Lambda build 83.
>>>>>
>>>>> Thanks
>>>>> Anna
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>> !DSPAM:35,515bfca371141724266025!
>>>>
>>
>



More information about the lambda-dev mailing list