Overload resolution simplification

Zhong Yu zhong.j.yu at gmail.com
Thu Aug 15 16:08:35 PDT 2013


On Thu, Aug 15, 2013 at 4:56 PM, Maurizio Cimadamore
<maurizio.cimadamore at oracle.com> wrote:
> On 15/08/13 22:36, Zhong Yu wrote:
>>
>> On Thu, Aug 15, 2013 at 9:00 AM, Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com> wrote:
>>>
>>> On 15/08/13 14:24, Zhong Yu wrote:
>>>>
>>>> That is not a reason for Java to reject it too. Java traditionally
>>>> does inference based on assignment context; it'll be nice to continue
>>>> to do that even with lambda arguments.
>>>>
>>> Well - that wasn't the point of my email; several posts in this thread
>>> were
>>> of the kind - 'why can't you guys just do what C# does' ?
>>> I only tried to show that there are similar limitations elsewhere.
>>>
>>> I explained at least 3-4 times as to why it is actually a good design
>>> choice
>>> not to allow stuff as Comparator.comparing overload - but somehow the
>>> message doesn't get across. It's not like we are making something dumber
>>> or
>>> different from what it used to be; it's true Java does inference based on
>>> target context - but that inference has _never_ affected the outcome of
>>> overload resolution - which helps overload selection to remain tractable
>>> (i.e. not NP-hard, to go along with Eric Lippert). We'd like to keep it
>>> that
>>> way. That means sticking with a design principle that guided us in the
>>> past
>>> - but I do understand that much of this stuff is subtle and hard to
>>> disgest.
>>>
>>> Maurizio
>>
>> I've been only arguing for the limited overload case where all
>> overloaded methods must agree upon the parameter types of implicit
>> lambda arguments. That is a tractable strategy. In your previous
>> example.
>>>
>>> m(x->g(y->f(...)))
>>> where m, g, f are overloads.
>>
>> if m,g,f satisfy the requirement about lambda parameter types, it is
>> as tractable as
>>    m( (X x)->g( (Y y)->f(...) ) )
>> If m,g,f don't satisfy the requirement, fail immediately.
>>
>> Your other objection is that lambda parameter types may depend on
>> method type variables; but it seems to me that we can first infer
>> method type variables from other arguments and assignment target,
>> after which the lambda parameter types are resolved per method,
>> therefore we can check whether all methods agree upon lambda parameter
>> types. This is done before selecting the most specific method.
>
> In the complex cases (such as Comparator.comparing) this is almost always
> the case; the lambda parameter type depends on some method type variable.
> Now, if the method type-variable is in a position that doesn't overlap with
> the return type, fine, we could do that (in fact that's how javac worked
> until last week).
>
> If there's an overlap between the return type and that method type-variable,
> then you have two choices:
>
> *) you throw the context into the overload machinery - thus making the
> problem much harder - i.e. in cases like
>
> m(g(x-> ...)) [see below]
>
> *) you throw the context or give up depending on what kind of context is -
> i.e. if assignment context then it's ok [see below]
>
> *) you give up (what javac did)
>
>
> So, to stress the point I'm making - in a case like this:
>
> SomeTarget s = g(x-> ...)
>
> you have only one target to consider when you do overload selection of g. In
> this case, however:
>
> m(g(x-> ...))
>
> You have multiple targets to throw into the overload selection for g - one
> for each m overload. This means overload resolution grows exponentially with
> the level of nesting.

Yes, I'm not saying this example should work.

>
>
>
>>
>> This process may be too complex for programmers to follow, which is
>> probably Dan's original point. I don't think people care. Nobody reads
>> the 40 page long JLS section 15.12, yet people are doing ok based on
>> intuition. I believe people's intuition can handle the limited
>> overload capability too; in all examples shown so far, none is
>> difficult to understand if the method is overloaded and the compiler
>> accepts the invocation. It is more difficult to understand why
>> overloading does not work in these cases.
>
> The problem is that people (not necessarily users) is gonna need to read
> that JLS section - as they will have to implement IDEs or different
> compilers. Do we want _all_ compilers in the world to sign up for that kind
> of combinatorial explosion? AFAIK none of the IDEs out there (but Netbeans,
> which uses javac itself as a backend) implements the full overload/inference
> check as described in the spec and as was implemented in javac - and you

hey, even javac doesn't "implements the full overload/inference check
as described in the spec" :)

> know what? People didn't even realized that when using them.
>
> Maurizio
>>
>>
>> Zhong Yu
>
>


More information about the lambda-spec-observers mailing list