> On Oct 12, 2018, at 11:15 AM, Brian Goetz <[email protected]> wrote:
>
> We have some precedent for resolution that involves "try both", which is the
> Class::method syntax, where we'll match either an instance method or a static
> method passing the receiver as the first parameter. However, this is a
> little different; in that case, we were still using all the parameters, just
> adapting them to paper over the somewhat accidental static/instance divide.
> In this case, we want to drop the receiver when the wired-to method doesn't
> want it, which is a little messier. But, also not totally novel; when
> adapting a value-returning method reference to a void-returning SAM, we are
> willing to drop the return value.
>
> There are (at least) two ways we could attack this. The first involves
> refining the "infer a target type from the method descriptor, and then use
> that for overload selection" intuition. Just as with Class::method, where
> we use the target type to do overload selection for both static and instance
> methods, and fail if we find neither or both, we can do the same thing;
> construct both the with-receiver and without-receiver SAM, and fail if there
> is not exactly one answer.
The intuition I would lean on is overload resolution. The '=' that binds a
method implementation is an overloaded operator, because there are multiple
function types that could be suitable.
void bindCompareToImplementation(ToIntFunction<T> mref);
void bindCompareToImplementation(ToIntBiFunction<Foo,T> mref);
void bindSizeImplementation(IntSupplier mref);
void bindSizeImplementation(ToIntFunction<Foo> mref);
{
bindCompareToImplementation(c::compare);
bindSizeImplementation(myList::size);
}
(This also makes me less worried about extra complexity—it's the kind of
complexity we already handle in overload resolution.)