Comparator combinators
Brian Goetz
brian.goetz at oracle.com
Wed Aug 14 12:49:45 PDT 2013
This may well be our last API loose end...
We currently have a pile of Comparator combinators, all currently called
comparing() or thenComparing(). Regardless of whether we choose to go
forward with the simplified overloading plan, these overloads have a
problem: for implicit lambdas, we can't distinguish between
comparing(T->U)
and
comparing(T->int)
because we don't type-check the body of the lambda until we do overload
selection, and don't do overload selection based on whether there are
type errors in the body (this was roundly rejected as being too
brittle). So for lambdas like:
comparing(x -> x.size())
we've got a circularity -- even under the older, more complex scheme.
We'd thought perhaps that, if we adopted the heuristic that we can
eagerly give a type to method reference that refers to a non-overloaded
method (e.g., Person::getAge), then cases like
comparing(Person::getAge)
can be handled, and this might take some of the pressure off the problem.
For lambdas (with either approach) you can always get what you want with
an explicit lambda:
comparing((Person p) -> p.getAge())
since this can be type-checked early.
So the question is, is this good enough, even though it falls afoul of
the overloading guidelines for implicit lambdas? Or, should we mangle
the names of the methods?
This question comes down to whether we think its better to force
everyone to explicitly pick a method, but then supporting implicit lambdas:
comparingInt(x -> x.size())
or forcing users to use non-ambigous method refs or explicit lambdas:
comparing(Person::getAge)
or
comparing((Person p) -> p.getAge())
Which disambiguation approach is worse?
More information about the lambda-libs-spec-observers
mailing list