Overload resolution simplification
maurizio cimadamore
maurizio.cimadamore at oracle.com
Sat Aug 10 11:07:54 PDT 2013
On 10-Aug-13 6:35 PM, Zhong Yu wrote:
> 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?
You are right - was looking in the wrong place.
>
> If we cannot overload them, it'll be quite clumsy:
>
> comparingInt(person::age).thenComparingDouble(person::height)
>
> looks like Hungarian notation:)
Sure - but one bit of the hungarian notation (comparingInt) is
unavoidable. And, I think it would be equally bad if half the API used
overload and the other half used name mangling, based on some obscure
compiler/language limitation.
Maurizio
>
>
> 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