Bikeshed opportunity: compose vs composeWith (original) (raw)
Remi Forax forax at univ-mlv.fr
Tue Nov 27 07:16:56 PST 2012
- Previous message: Bikeshed opportunity: compose vs composeWith
- Next message: Bikeshed opportunity: compose vs composeWith
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 11/26/2012 11:57 PM, Brian Goetz wrote:
I like the "then" convention to indicate sequencing. In context:
people.sort(comparing(Person::getLast) .thenCompare(comparing(Person::getFirst))) or people.sort(comparing(Person::getLast, Person::getFirst)) (comparing is a static method so it can be annotated with @SafeVarargs). This one falls apart as there is no common supertype between Function<Person, T extends Comparable> and IntFunction so people will try people.sort(comparing(Person::getLast, Person::getHeight)) and be mystified by the error message they get. And then ask for a combinatorial explosion of comparing() methods.
Ok, trying to implement it ...
public class PrimitiveFunctions { interface Function<T, U> { public U apply(T element); }
interface IntFunction extends Function<T, Integer> { @Override public default Integer apply(T element) { return applyInt(element); }
public int applyInt(T element);
}
@SafeVarargs @SuppressWarnings("unchecked") public static Comparator comparing(Function>... functions) { if (functions.length == 0) { throw new IllegalArgumentException(); } return (o1, o2) -> { for(Function> function: functions) { int diff = ((Comparable)function.apply(o1)).compareTo(function.apply(o2)); if ( diff != 0) { return diff; } } return 0; }; }
public static void main(String[] args) { Comparator c1 = comparing(s -> s.length(), s -> s.charAt(0)); Comparator c2 = comparing((String s) -> s.length(), (String s) -> s.charAt(0)); Comparator c3 = comparing(String::length, String::hashCode); //System.out.println(c.compare("foo", "bar")); } }
c1 doesn't compile, comparing is a varargs and the lambda doesn't define its parameter type, so there is a cyclic inference here. This is a known issue of current inference algorithm (see an old discussion with Dan about that). I think it's fixable, but I'm not sure
c2 compiles :)
c3 doesn't and I don't understand why. PrimitiveFunctions.java:38: error: method comparing in class PrimitiveFunctions cannot be applied to given types; Comparator c3 = comparing(String::length, String::hashCode); ^ required: Function>[] found: String#length,String#hashCode reason: Cannot instantiate inference variables T because of an inference loop where T is a type-variable: T extends Object declared in method comparing(Function>...) 1 error
cheers, Rémi
- Previous message: Bikeshed opportunity: compose vs composeWith
- Next message: Bikeshed opportunity: compose vs composeWith
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the lambda-libs-spec-observers mailing list