Search code examples
javajava-8functional-programmingpecs

When to use PECS when designing a library?


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.


Solution

  • 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)