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