Overload resolution simplification

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Sat Aug 10 06:56:35 PDT 2013


On 10/08/13 08:07, Andrey Breslav wrote:
> The case of overloaded method references worries me as well (lambdas are ok). Note that C# supports overloaded method references (method groups) as arguments and only as arguments. It seems that inference can disambiguate method references rather well if we stick to what Dan proposes about lambdas, because for a method reference there is no body to check. But maybe I'm missing something.
I believe C# is very different w.r.t. Java when it comes to 
target-typing and overload resolution - as such C# is not subject to all 
the issues we have here with 'stuck' expression - i.e. expression such 
as lambda and/or method references that cannot be looked at by the 
compiler because some type information is missing and the compiler 
cannot safely go ahead and instantiate the inference variable that would 
make it possible for the compiler to go ahead.

I think 'comparing' is a good example of what can go wrong; even if we 
added support for overloaded method references (which we had last week), 
that API cannot be compiled by passing in a method reference, as the 
inference variable that is keeping the method reference stuck also 
appears on the 'comparing' return type. Which is, IMHO, a much more 
subtle explanation than 'just don't use an overloaded method reference 
here'.

If we could have a scheme that worked in all cases, then I'd be totally 
in favor of having a more complex scheme. But, because of Java legacy, I 
don't think such an approach exists here.

The only incremental improvement I see viable here, one that has been 
discussed before, would be to add some logic to detect that all 
overloaded methods force the same choice on the implicit lambda 
parameter/overloaded mref; that would be enough to get past Remi example 
- but it doesn't scale too well to generic methods.

Maurizio

>> On Aug 9, 2013, at 2:21 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>>
>>> Also I've a nice parsing framework that use type specialised lambda to avoid boxing that doesn't compile anymore.
>>>
>>> public IntStream parse(BufferedReader reader, ToIntFunction<String> fun) {  ... }
>>> public LongStream parse(BufferedReader reader, ToLongFunction<String> fun) { ... }
>>>
>>> when called like this: parse(Integer::parseInt).
>> Thanks for the use case.
>>
>> The 'parse' method is essentially the same shape as the 'map' method that was discussed by the EG quite a bit, with the eventual conclusion that it would be clearer to give each method a different name (parseInts, parseLongs, etc.).
>>
>> http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-February/001417.html
>> http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-March/001441.html
>> http://mail.openjdk.java.net/pipermail/lambda-libs-spec-experts/2013-March/001458.html
>>
>> Doesn't mean that all other developers must follow our lead, but the fact that the EG tried it and then concluded that it didn't want overloading here is a strong argument that this is potentially a bad convention to follow.
>>
>> If somebody likes this convention anyway, then we made a special-case effort to support method references.  Unfortunately, Integer::parseInt is overloaded and so outside of the set of supported method references.  As I mentioned in the EG meeting, by drawing the line like this, it's great when it works, and annoying when it doesn't and you fall off of a cliff.  We considered using arity (e.g., "is this overloaded with arity 1?"), but that just moves the line, rather than solving the problem.
>>
>> So, I don't love the cliff, but I don't have a good alternative, other than just not having any special treatment at all.
>>
>> —Dan



More information about the lambda-spec-observers mailing list