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