Overload resolution simplification
Michael Hixson
michael.hixson at gmail.com
Sat Aug 10 08:30:02 PDT 2013
On Sat, Aug 10, 2013 at 8:17 AM, maurizio cimadamore
<maurizio.cimadamore at oracle.com> wrote:
> On 10-Aug-13 3:41 PM, Michael Hixson wrote:
>>
>> I'm sure I sound like the most Comparator-obsessed guy in the world at
>> this point, but I have to ask...
>>
>> For a brief time, the Comparator.thenComparing methods had signatures like
>> this:
>>
>> <S extends T> Comparator<S> thenComparing(Comparator<? super S> other);
>>
>> Those "narrowing type" changes were reverted for some reason, removing
>> the <S> type parameter. Did it have to do with this topic -- the
>> ability of the compiler to interpret lambdas/method references in
>> overloaded methods? Was that one of the "complex overload
>> disambiguation scenarios" that was abandoned?
>
> I believe so - the signature above has same problems as the 'comparing' one
> - the compiler can't do much with it, regardless the approach.
>
> Maurizio
>
That's precisely what I was getting at. If the current situation is
no better than the one that led to removing the <S>, then why remove
the <S>? I thought it was removed due to the compiler being unable to
infer <S> in lambdas and method references. If we'll have to specify
types in those situations anyway, that explanation no longer makes
sense.
I could be entirely off-base here. If I'm mixing up issues, just tell me so.
-Michael
>>
>> -Michael
>>
>> On Sat, Aug 10, 2013 at 6:56 AM, Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com> wrote:
>>>
>>> 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