John Rose john.r.rose at
Mon Jul 15 13:33:29 PDT 2013

On Jul 15, 2013, at 8:53 AM, Marc Petit-Huguenin <marc at> wrote:

> I am trying to use a comparator on a Map.Entry<String, Integer> stream, and I
> am not sure why this does not compile:
> .sorted(Comparator.comparing(Map.Entry::getValue))

IMO, the language and APIs (apart from the fine print of the inference rules) seem to promise that this sort of expression works in the naively coded form.

By "this sort" I mean a combination of a fluent chain x.a(#).b(#) including behavior-adjusting sub-expressions, either x.a(#).b(f(g(#)) or even x.a(#).b(y.f().g(#)), where the # can contain type-inferred lambdas or MRs.

Just under the surface of the language, the "fluent" idiom really means the first (receiver) argument x gets special syntactic treatment, allowing a chainable infix syntax x m (args) instead of the function-style prefix notation m(x, args).  Under the hood, and after names are resolved, a chain x.a(#).b(#).c(#) is presented to the JVM about the same as if it were coded in prefix notation c(b(a(x,#),#),#).  The API designer should have (IMO) a free choice between the two surface syntaxes.  If this is to be true, then the enhanced type inference algorithm should treat the two syntaxes with parity.  (Even though the scoping rules for a,b,c are very different.)  If there is not to be parity, then we need to give rules of thumb on where the inferencer will give up (and/or make the error messages far more directive).

Put simply, either idioms like the one Marc ran into should work routinely (without explicit type arguments), or else there has to be some very clear practical guidance to ordinary users when and where to write the explicit type arguments.

I would hope that the inferencer can help the user in many cases like Marc's.

— John

More information about the lambda-dev mailing list