0

I am working on a library which makes heavy use of functional interfaces and currently struggle whether to apply PECS or not:

Predicate<A>
Function<A,B>
BiFunction<A,B,C>

vs.

Predicate<? super A>
Function<? super A, ? extends B>
BiFunction<? super A,? super B,? extends C>

It just seems so cluttered and even the error messages turn from:

Incompatible types: Function<Item, Long> is not convertible to Function<Item, String>

to something like

Incompatible types: 
Function<capture of ? super Item, capture of ? extends Long> is not 
convertible to Function<capture of ? super Item, capture of ? extends String>

which is so hard to read. I have read the following question but still struggle whether to apply it or not as it pollutes the library code and worsens the compiler error messages. Personally I would opt for PCES for the Predicate<A> variants.

Is there some guideline whether to apply PECS or not? I know the pros and cons but I wonder how often people really store e.g. Predicate in fields as lamdas and method references are not affected by what PECS offers. I did not find any further advice on the web. Here is one of the classes affected by this.

roookeee
  • 1,710
  • 13
  • 24
  • 4
    that linked answer says it all - you might think you don't need it or actually find a use case for it _at the moment_, but experience says some users using your library might hate you in the long run. Weird closed as opinion based btw, I don't find it as such... – Eugene May 26 '19 at 19:03
  • 1
    It's not that simple: PECS degrades the library readability, users with very little generic knowledge may get confused by the enormous length of the type parameters which makes it harder to deduce what a function does (its signature is not easily understandable) and we get worse error messages. The users affected by it could still do `t -> mismatchPredicate.test(t)` – roookeee May 26 '19 at 19:05
  • 3
    users with little generic knowledge should not be using a generic library to begin with - but learn generics; this is a very bad argument to me. – Eugene May 26 '19 at 19:06
  • Most developers I know understand `T` and `T extends Somestuff` but there are more people I know which do not know anything about `? super T` or anything related to wildcard bounds. But it seems like this is pretty opinioated, your viewpoint is not wrong too – roookeee May 26 '19 at 19:12
  • 6
    the issue might be viewed from a different angle too: because the jdk libraries use PECS, of course, users might be making use of `? extends/super` without even realizing why this works - you might be breaking their perspective on that. you can't make everyone happy. – Eugene May 26 '19 at 19:15
  • Haha fair point :) – roookeee May 26 '19 at 19:15
  • 1
    same Holger from the linked answer shows an interesting way to do whatever you are doing in your GitHub project too... have a look [here](https://stackoverflow.com/a/54294733/1059372), may be useful... – Eugene May 26 '19 at 19:29
  • Thanks eugene, my library is quite similar compared to the basic idea outlined in the linked answer but uses a fluent builder like api to accomplish a highly configurable way of defining data mapping, even for immutable data structures – roookeee May 26 '19 at 21:12
  • 3
    Fun fact: even the OpenJDK core developers get this [wrong](http://openjdk.5641.n7.nabble.com/RFR-s-8152617-add-missing-wildcards-to-Optional-or-and-flatMap-tt288184.html#none) sometimes. – Stefan Zobel May 26 '19 at 22:14
  • Interesting - at least its a backwards compatible change – roookeee May 26 '19 at 22:25

1 Answers1

1

As discussed extensively in the comments below the main post: consistency and alignment to the JDK / standard library and its use of PECS with the gained compatability improvement by using PECS is a good argument to always use PECS (at least when designing libraries)

roookeee
  • 1,710
  • 13
  • 24