Overload resolution simplification
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Thu Aug 15 05:30:36 PDT 2013
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)=>"");
}
}
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