Overload resolution simplification

Zhong Yu zhong.j.yu at gmail.com
Sat Aug 10 10:35:58 PDT 2013


On Sat, Aug 10, 2013 at 12:23 PM, maurizio cimadamore
<maurizio.cimadamore at oracle.com> wrote:
> On 10-Aug-13 4:30 PM, Michael Hixson wrote:
>>
>> 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 believe we are talking about two different methods - thenComparing used to
> be less problematic as it was changed (as you say) not be be a generic
> method, so that problems with stuck lambdas/overloaded method references
> were no longer biting. Since thenComparing is also not overloaded, I don't

Maurizio, don't we have

    thenComparing(T->U)
    thenComparing(T->int)
etc?

If we cannot overload them, it'll be quite clumsy:

    comparingInt(person::age).thenComparingDouble(person::height)

looks like Hungarian notation:)


Zhong Yu


> see any problem in using this method with the simplified approach too.
>
> Maurizio
>
>>
>> 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