Overload resolution simplification

maurizio cimadamore maurizio.cimadamore at oracle.com
Sat Aug 10 10:41:13 PDT 2013

On 10-Aug-13 5:50 PM, Zhong Yu wrote:
> I'd appreciate that very much! The map() overloading use case wouldn't
> be rare in practice. People will feel bad if javac cannot see that the
> lambda parameter type is obviously fixed.
While I'm sympathetic with this position, this would mean that stuff like

IntStream map(IntFunction<T>)
<Z> Stream<Z> map(Function<T, Z>)


would work, while the following 'static' variant:

<U> IntStream map(Stream<U> s, IntFunction<U>)
<U, V> Stream<V> map(Stream<U>, Function<U, V>)

Stream<String> ss = ...
map(ss, x->1);

Would _not_ work. And it feels a bit weird - if the first case is deemed 
important, the second is equally important - it's just same example in a 
different style.

Then I guess next step would be to say - obviously javac can see what 
'U' is by looking at the input stream. Which is essentially where we 
were: in this case instantiating U is fine but there are cases 
(Comparators.comparing) where it's not ok. And it seems like not 
everybody is comfortable in making those subtle distinctions.

It's obviously a problem of 'where to draw the line'. But there are 
advantages in scaling back a bit and give up a bit of expressiveness as 
the model you get is much simpler to explain and so are its boundaries. 
This property is not to be underestimated.

Note that the 'same parameter' rule you are advocating for requires 
global reasoning: to see whether a lambda can be type-checked you have 
to consider all matching signatures and see if they impose same 
parameter on the implicit lambda. This can be trivial to see in simple 
examples (such as map) - but what if the example is more convoluted? 
I.e. many overloads? Or different sam types using different ordering for 
type parameters i.e.

Function1<X, Y> {
    Y apply(X x)

Function2<X, Y> {
    X apply(Y x)

I believe that in such cases (or even more complex ones with nested SAM 
types as type-parameters) we'll be essentially at compiler's mercy - 
i.e. it would be very hard to judge whether a method call would succeed 
w/o trying it first on javac. And that's bad too.


More information about the lambda-spec-observers mailing list