On May 6, 2015, at 1:58 PM, Attila Szegedi <[email protected]> wrote:
> On May 6, 2015, at 12:37 PM, Paul Sandoz <[email protected]> wrote: >> >> >> On May 2, 2015, at 11:31 PM, Remi Forax <[email protected]> wrote: >> >>> Hi all, >>> today, I stubble on a variant of JDK-8050818 [1], >>> trying to call negate() on a lambda which is not yet a Predicate (due to >>> target typing) which requires either to cast the lambda to a Predicate and >>> everybody knows that cast are evil or to add a local variable. >>> >>> I think there is a way to fix that, it's not very orthodox so I let you >>> judge. >>> The idea is to introduce a static method 'of' on Predicate, >>> class Predicate<T> { >>> ... >>> public static <T> Predicate<T> of(Predicate<T> predicate) { >>> return predicate; >>> } >>> } >>> >>> so one can write: >>> stream.filter(Predicate.of(String::isEmpty).negate()) >>> compared to >>> stream.filter(((Predicate<String>)String::isEmpty).negate()) >>> >>> so the question is, does it it worth the cost to introduce a static method >>> that basically do nothing on all functional interfaces of >>> java.util.function. >>> >> >> That does have the virtue of not adding a static method per operation but i >> still cannot bring myself to add such methods as a work around for seems >> like a compiler inference problem (albeit one in which might be very tricky >> or not possible to solve). > > I think it is firmly in the category of “very tricky”, but probably still > possible, albeit (from my point of view) undesirable. > > String::isEmpty will not, on its own, have a method named .negate(); the > compiler can’t really infer the programmer’s intent to make it into a > Predicate, not without a fairly high level reasoning (filter needs a > Predicate; should the compiler perform an exhaustive search of the visible > functional interfaces to see which one has a method with signature “Predicate > negate()”?). So, yeah, it seems like in this case the programmer needs to > communicate the intent. > > I think inference would be *possible*, but it’d be expensive, and would still > allow for either ambiguities or accidentally matching something unexpected, > so I think it would also be undesirable. > Ok. > I don’t have an opinion of whether we want an “of” static method on > Predicate, as then it would have to indeed be introduced on many other > interfaces. It’s more appealing than a cast, certainly; especially since the > cast apparently needs to specify the explicit type parameter too. > I guess it's too late to consider an implicitly declared method along the lines of what Remi suggests. FWIW i always found such methods on enum a little too magical. And perhaps it's too confusing to consider an invocation mode where "this" can be an implicit first parameter. >> >> In some respects i wonder if the default methods on the functional >> interfaces are an attractive nuisance. > > Meaning, if .negate(Predicate) were a static method on the Predicate class > instead of a default method, then > stream.filter(Predicate.negate(String::isEmpty)) would be possible? Yeah… > Yeah. We are now in the unfortunate position where to alleviate this problem we might require duplicate static and default methods. I have been sitting on the issue a bit and nearly closed it a few times :-) Paul.
