Overload resolution simplification
Zhong Yu
zhong.j.yu at gmail.com
Thu Aug 15 06:24:58 PDT 2013
On Thu, Aug 15, 2013 at 7:30 AM, Maurizio Cimadamore
<maurizio.cimadamore at oracle.com> wrote:
> Here's an example in C# that features similar problems as the
> Comparator.comparing case (I beg your mercy for my horrible C# skills :-)):
>
> class Test<T>
> {
> delegate object Delegate1<X>(X s);
> delegate string Delegate2<Y>(Y s);
>
> static Test<Z> m<Z>(Delegate1<Z> d1) { return null; }
> static Test<Z> m<Z>(Delegate2<Z> d2) { return null; }
>
> static void test()
> {
> Test<string> ts = m((x)=>"");
> }
> }
That is not a reason for Java to reject it too. Java traditionally
does inference based on assignment context; it'll be nice to continue
to do that even with lambda arguments.
>
> We have two overloads, each accepting a slightly different delegate; the two
> delegates are generic (like our comparing SAMs) and they differ only in the
> return type - Delegate2 has a more specific return type. Both methods return
> a Test<Z>, where Z is the same type-variable used to parameterize the
> delegate. If I compile this with my crappy mono compiler I get:
>
> Test.cs(11,27): error CS0411: The type arguments for method
> `Test<T>.m<Z>(Test<T>.Delegate1<Z>)' cannot be inferred from the usage. Try
> specifying the type arguments explicitly
>
> Which seems to be in sync with my understanding of Eric's posts. You need to
> supply another argument to unblock inference for the lambda body; otherwise
> the body won't be used. I.e. this works:
>
> class Test<T>
> {
> delegate object Delegate1<X>(X s);
> delegate string Delegate2<Y>(Y s);
>
> static Test<Z> m<Z>(Delegate1<Z> d1, Z z) { return null; } //additional
> param here
> static Test<Z> m<Z>(Delegate2<Z> d2, Z z) { return null; } //additional
> param here
>
> static void test()
> {
> Test<string> ts = m((x)=>"", ""); //additional actual here
> }
> }
>
> So, while I don't trust my unofficial C# compiler too much, this seems to
> confirm that C# has similar boundaries to what we have in Java. It just
> happens to be less of an issue in C# where there are much less overloads
> because of primitives.
>
> Maurizio
>
>
> On 15/08/13 10:30, Ali Ebrahimi wrote:
>>
>> Hi,
>> This [1] is another post from Eric.
>>
>> [1]
>> http://ericlippert.com/2012/10/02/how-do-we-ensure-that-method-type-inference-terminates/
>>
>>
>> On Thu, Aug 15, 2013 at 4:12 AM, Ali Ebrahimi <ali.ebrahimi1781 at gmail.com
>> <mailto:ali.ebrahimi1781 at gmail.com>> wrote:
>>
>> Hi,
>>
>> On Thu, Aug 15, 2013 at 1:59 AM, Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com
>> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>>
>> On 14/08/13 19:57, Ali Ebrahimi wrote:
>>
>> Hi,
>> please reread Eric's last two paragraph again[1]:
>>
>> I think I read it well - I just believe Eric is talking about
>> two different kinds of information flow:
>>
>> 1) return type constraints on methods cannot influence
>> overload resolution [as in Java]
>>
>> 2) lambda return value constraints CAN influence overload
>> resolution [as in Java]
>>
>>
>> 3) lambda return value constraints CAN also influence type
>> inference (as in C#, based on my understandings from C#'s Spec &
>> Eric's blog)
>>
>>
>> The big question mark is: how do I get to a lambda return
>> value constraint? Well, you have to be able to check the
>> lambda first; and when can you do that?
>>
>> when you don't turn off type inference.
>>
>> When you have a grip on the _instantiated_ lambda parameter
>> types. This, I believe, means that in certain cases,
>> restriction (1) will play an important factor, as certain
>> lambdas will not be checked (or will be checked with
>> sub-optimal parameter types?) and you won't get what you
>> expect. More or less what you get with Comparator.comparing.
>>
>>
>> Regards,
>> Ali Ebrahimi
>>
>>
>
More information about the lambda-spec-observers
mailing list