Overload resolution simplification

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Aug 15 16:14:56 PDT 2013


On 15/08/13 23:54, Ali Ebrahimi wrote:
> Hi,
>
>
> On Fri, Aug 16, 2013 at 2:57 AM, Maurizio Cimadamore 
> <maurizio.cimadamore at oracle.com 
> <mailto:maurizio.cimadamore at oracle.com>> wrote:
>
>     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
>>         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
>
> My concerns is for overloaded methods with lambda arguments, which 
> currently compiler give up them.
If all overloads have a SAM with same arity - yes, compiler gives up; if 
arity can be used to prune, no it doesn't give up. That's more frequent 
than you'd think.
>
>>
>>     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 ?
>
> yes, of course for inferring method's type args and finaly for 
> lambda's input type args.
If that's the case, see my reply to Zhong Yu, as I believe your proposed 
scheme has the same complexity shown there. Not to mention that your 
scheme also features a degree of brittleness that the EG unanimously 
rules out - i.e. any error in the lambda body can make the method become 
inapplicable - this means that seemingly refactorings of a method in 
some API might trigger change in overload selection of methods that 
receive a lambda calling that API - ouch!

Maurizio
>
> Regards,
> Ali Ebrahimi



More information about the lambda-spec-observers mailing list