Overload resolution simplification

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Aug 15 15:27:02 PDT 2013


On 15/08/13 23:21, Ali Ebrahimi wrote:
> Hi Maurizio,
>
> On Thu, Aug 15, 2013 at 5:00 PM, Maurizio Cimadamore 
> <maurizio.cimadamore at oracle.com 
> <mailto: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)=>"");
>         }
>     }
>
>     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
>
> This is because C# does not do assignment context inference.
> But:
> Test<string> ts = m<string>((x)=>"");
Yep
or

Test<sting> ts = m((string x)=>...)
>
>
>     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
>         }
>
> This is currently fails in java.
Yep it does. Always has, always will :-)
>
> Don't get me Wrong. If you have in mind I said we can learn from C# 
> not copy it as C# learned (even copy) from java in past.
> So my intend is combination of current java solution (assignment 
> context inference which C# does not support) and C#'s one (lambda 
> return type inference).
I guess then I'm missing what is that you think makes C# lambda return 
inference different from what we have in Java
>
> We type check lambda body only if all its input type arguments already 
> inferred from inference context:
>     static class Test<T>{
>         Comparator<String> m(){
>             return Comparator.comparing(t -> t.length()); [1]
>         }
>
>         static <P> void m(Comparator<P> c, P t){
>             return;
>         }
>
>         void m(Comparator<T> c){
>             return;
>         }
>
>         void test() {
>             new Test<String>().m(Comparator.comparing(t -> 
> t.length()));  [2]
> ((Comparator<String>)Comparator.comparing(t -> 
> t.length())).toString(); [3]
>             Comparator<String> c = Comparator.comparing((String x) -> 
> 0); [4]
>             m(Comparator.comparing((t) -> t.length()),""); [5]
>         }
>     }
>
> For overloaded methods we act in multiple phases.
> phase1: we do type check lambda without boxing, unboxing and widening 
> in return type.
> if we get only one overload that successfully type checks lambda So 
> inference has been succeed, otherwise go phase 2.
>
> phase2: we do type check lambda without boxing and unboxing but with 
> widening in return type. if we get only one overload that successfully 
> type checks lambda So inference has been succeed, otherwise go phase 3.
>
> phase3: we do type check lambda with boxing, unboxing and widening in 
> return type. if we get only one overload that successfully type checks 
> lambda So inference has been succeed, otherwise ERROR.
Do you plan to use information about i.e. assignment context when doing 
steps 1/2 ?

Maurizio
>
>
> One note:
> My intention is only to improve and modernize java. java is my all day 
> work.
>
> Regards,
> Ali Ebrahimi
>



More information about the lambda-spec-observers mailing list