Review request for initial lambda functions and utils

Kevin Bourrillion kevinb at
Wed Aug 10 08:10:45 PDT 2011

Apologies for a long tangent that seems to be all about Guava, but of course
we want the JDK libraries to make the best decision on this, whatever it may

On Wed, Aug 10, 2011 at 6:22 AM, Rémi Forax <forax at> wrote:

> Just fix foo() and this works.  No explicit type parameters needed.
> Right, if you change the test case, the bug disappear !
> More seriously, I don't control foo().

That's unfortunate.  There is no valid reason under the sun that I can
imagine for refusing to accept a Predicate<Object> when you wish to apply it
to a String.  That API is broken and should be fixed.  (I believe the quote
is, "An API should work.")

Moreover, since you don't control either foo() or Guava, what is it that
makes you conclude that foo() is more correct than we are?

You may not believe this, but we did our best to entertain the notion that
Guava should do what it can to try to "protect" users from having to suffer
with those Nasty Ugly Wildcards.  We thought, wildcards are ugly and maybe
we can prevent users from needing to deal with them!  But we can't.  We came
to accept that they are the *fact of the matter*; that's the way the design
of Java generics works and everyone has to either work with that or face the
consequences (or, as in your case, make their *users* face the consequences,
as the maintainers of foo() have done).

It would be improper for compose(p, f) to return a Predicate<String> because
> a Predicate<Object> is *what it is*.  It's a predicate that's capable of
> handling any object.  There are very rare circumstances (well, rare when
> APIs are designed correctly) where you are forced to "pretend" that a
> Predicate is less capable than it really is.  Cast-and-suppress is a
> perfectly reasonable escape valve for those situations.
> I can't disagree more, it's a common pattern when you want to share
> lambdas.
> Example, I want to share/reuse a projection function (your Function) to
> take different types
> knowing I will call toString() or hashCode() on the parameter of the
> projection function,
> I will define the function once taking an Object even if the resulting
> Predicate
> returns different types.
>     <T> Predicate<T> toStringCompose(Predicate<T> predicate) {
>       return Predicates.compose(predicate, TO_STRING_FUNCTION);
>     }

Hmm... do you mean the argument type to be Predicate<String>?  I'll assume
that.  If you compose a Predicate<String> with Functions.toStringFunction(),
which is a Function<Object, String>, what you get is a Predicate<Object>,
and what you should return from toStringCompose() is a Predicate<Object>.
 What is it? A Predicate. What type is it capable of accepting? An Object.
 There it is: Predicate<Object>.

The fact that I will later apply this to an Integer is not relevant at this
point.  The type reflects what the instance *is* than about what limited
ways you expect to *use* it.  If I then want to use it with a Double, I
won't have to call toStringCompose() again.

Another example, I have two classes A and B with B that inherits from A,
> A defines a field (or a property). The projection function is defined to
> take an A
> and returns the value of the field. I can create a predicate on a A or on a
> B,
> I will not write the projection function twice, I will reuse the same
> function
> and compose to create a Predicate of A or B.

I'll assume for now this works out similarly to the previous example, but we
can explore it more if needed (code would help).

> So it's perhaps you haven't seen these use cases because there is no method
> reference
> in Java but as you know it will change.

We see these use cases constantly, and Guava supports them naturally.

> And I don't want to cast (and suppress) something i.e. add noise to my
> program
> just because you think everybody should not call your API by providing the
> type
> argument explicitly.

Again: why not blame foo()?  It's the one that didn't read Effective Java.

Kevin Bourrillion @ Google
Java Core Libraries Team

More information about the lambda-dev mailing list