Review request for initial lambda functions and utils

Steven Simpson ss at comp.lancs.ac.uk
Wed Aug 10 13:16:35 PDT 2011


On 10/08/11 16:10, Kevin Bourrillion wrote:
> 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.")

I came to the same conclusion while trying to answer another point.  
Because there are no methods on Predicate which are blocked by using <? 
super T>, anything that requires a Predicate<T> can and should be 
written to accept a Predicate<? super T>.  However, if an API fails to 
do that, it's easy enough to have (say) a defender to downcast a Predicate:

   interface Predicate<T>  {
     <U extends T>  Predicate<U>  down(Class<U>  type)
       default Predicates.down;
   }

   class Predicates {
     static<T, U extends T>  Predicate<U>  down(Predicate<T>  p, Class<U>  type) {
       return #{ t ->  p.eval(t) }; // or p#eval
     }
   }

   void api(Predicate<String>  p) {
     // Oops, should take a<? super String>.
   }

   Collection<String>  coll;
   Predicate<Object>  p = Predicates.contains(coll);
   api(p); // error
   api(p.down(String.class));

If T/U is not a simple type, e.g. List/ArrayList<String>, I don't think 
you can write down(ArrayList<String>.class) - unless that's a 
forthcoming feature? - but since down() doesn't actually use the value 
of 'type', you could use some sort of marker type instead, and write:

   p.down(Marker.<ArrayList<String>>z())





More information about the lambda-dev mailing list