> On Oct 12, 2018, at 11:15 AM, Brian Goetz <brian.go...@oracle.com> 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.)