Lambda and method reference inference

Remi Forax forax at univ-mlv.fr
Thu Dec 6 14:01:21 PST 2012


On 12/06/2012 10:03 PM, Brian Goetz wrote:
> We did care -- a lot -- but in the other direction :(
>
> This is one of those things that seems obvious at first but in reality 
> has a poor cost-benefit balance.
>
> First of all, in your example, you can get what you want with:
>
>       A<Integer> c = (x, y) -> x + y;

it's not what I want, you can not do the same trick with:
   A<Integer> c = (int x, int y) -> x == y;
or
   A<Integer> c = (int x, int y) -> { list.add(x, list.remove(y)); }
or any calls that makes a difference between int and Integer.

>
> If you take the trouble to provide explicit parameter types, you are 
> saying "I want these exact types."  I can understand why you would 
> want the compiler to "just do what I mean", but allowing this degree 
> of flexibility unfortunately has a cost, and one of those costs is 
> more inference failures in other cases.

can you be a little more specific, which failures ?

>
> At the same time, the benefit is low -- to fix the problem, either 
> leave out the types and let the compiler infer them, or use the exact 
> types you need (there's a good chance your IDE will provide them for 
> you anyway.)  It's an easy and local fix.

The compiler infers the wrong type and I can't using the right type that 
exactly my problem.
The best I can do is introduce a temporary method which is really non 
intuitive

void foo(int x, int y) { list.add(x, list.remove(y)); }

A<Integer> c = (int x, int y) -> MyClass::foo;

and sorry, I don't believe that the IDE will cope with that (at least 
not before 2 years).
This 'feature' make even the job of IDE writer far more complex, by 
example refactoring a lambda to a method reference and vice-versa will 
have to deal with stupid discrepancies like this one.

>
> We do allow this flexibility for method references because the user 
> has no control over the types of the referred-to method the way he 
> does with lambda parameter types.  And method references exhibit more 
> inference failures.
>
> The semantics are modeled on the following intuition:
>  - typing for lambda expressions is like overriding a method;
>  - typing for method references is like calling a method.

I understand why when inferring a lambda with no specified type for 
formal parameter should be restricted to overriding rules but I don't 
understand why lambda with specified types for formal parameters has to 
have different rules different than the one for method reference.

cheers,
Rémi

>
>
> On 12/6/2012 1:56 PM, Remi Forax wrote:
>> I think i've already raised this point in August during the face to face
>> meeting and at that time nobody care, maybe this time, I will have more
>> chance :)
>>
>> with
>>      interface A<T> {
>>        T foo(T a, T a2);
>>      }
>>
>> this compile:
>>      A<Integer> b = Integer::plus;    // with plus defined as int
>> plus(int,int)
>>
>> but not this one:
>>      A<Integer> c = (int x, int y) -> x + y;
>>
>>
>> Can we, please, have the same rules for both method references and
>> lambdas that have their type of parameters specified ?
>>
>> cheers,
>> Rémi
>>



More information about the lambda-spec-experts mailing list