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