RFR: JDK-8319123 : Implementation of JEP-461: Stream Gatherers (Preview)

Tagir F. Valeev tvaleev at openjdk.org
Wed Nov 8 17:14:04 UTC 2023


On Wed, 8 Nov 2023 15:23:39 GMT, Viktor Klang <vklang at openjdk.org> wrote:

>> This is especially important given that often you don't know the AA type at all. E.g., imagine that you are doing `.andThen(Gatherers.fold(...))`, but `fold` returns `Gatherer<T, ?, R>`, so you can specify explicit `RR`, but not `AA`.
>
> Has this proven to be a problem for things like [Collectors.mapping(…)](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/Collectors.html#mapping(java.util.function.Function,java.util.stream.Collector)) ? 🤔 
> 
> There's one implication on turning it into a wildcard—it may actually cause issues implementing the composition directly in the override, as you won't have a typename to refer to.
> 
> Do you have a concrete example of where the current "encoding" causes a caller-problem?

The API should be client-friendly, not implementor-friendly, given that it's expected to have much more clients than implementors. An implementor can easily delegate to a private method to add missing type parameters. I did exactly this in the [teeing](https://github.com/openjdk/jdk/blob/7d25f1c6cb770e21cfad8096c1637a24e65fab8c/src/java.base/share/classes/java/util/stream/Collectors.java#L1913) Collector before. There should not be a reason to expose a parameter, which is merely an implementation detail. This also complicates the public documentation of the already complex feature, specifying the parameter which is not necessary to specify. 

> Has this proven to be a problem for things like [Collectors.mapping(…)](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/util/stream/Collectors.html#mapping(java.util.function.Function,java.util.stream.Collector)) ?

I'm not sure how I can prove this, given that you don't usually know the downstream accumulator, so if somebody hits this problem, they will be forced to solve it in another way (e.g., extracting parts of complex collector to separate variables), so you won't find the code in the wild which uses `mapping` type arguments explicitly. Yes, `Collectors.mapping` and `groupingBy` did this mistake in the past, and there's no reason to repeat it again.

> Do you have a concrete example of where the current "encoding" causes a caller-problem?

For example, I want to create a reusable gatherer that performs scan-concat and wraps every resulting string with '[...]'. First try:


var gatherer = Gatherers.scan(() -> "", String::concat)
  .andThen(Gatherer.ofSequential((_, t, pusher) -> pusher.push(STR."[{t}]")));


Now, the type of `gatherer` is `Gatherer<String, ?, Object>`, but I want `Gatherer<String, ?, String>`. I have the following alternatives:
1. Specify the variable type explicitly:

Gatherer<String, ?, String> gatherer = Gatherers.scan(() -> "", String::concat)
    .andThen(Gatherer.ofSequential((_, t, pusher) -> pusher.push(STR."[{t}]")));

2. Specify `ofSequential` type arguments:

var gatherer = Gatherers.scan(() -> "", String::concat)
    .andThen(Gatherer.<String, String>ofSequential((_, t, pusher) -> pusher.push(STR."[{t}]")));

3. Specify the types of lambda arguments explicitly:

var gatherer = Gatherers.scan(() -> "", String::concat)
    .andThen(Gatherer.ofSequential((Void _, String t, Downstream<? super String> pusher) -> pusher.push(STR."[{t}]")));

4. Specify `.andThen` type arguments:

var gatherer = Gatherers.scan(() -> "", String::concat)
    .<Void, String>andThen(Gatherer.ofSequential((_, t, pusher) -> pusher.push(STR."[{t}]")));

In all the cases, I need to specify explicitly more types than I need, as I need to specify only `String`. If we remove `AA`, then specifying `andThen` type arguments would be the shortest and the most readable alternative:


var gatherer = Gatherers.scan(() -> "", String::concat)
    .<String>andThen(Gatherer.ofSequential((_, t, pusher) -> pusher.push(STR."[{t}]")));

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/16420#discussion_r1386952517


More information about the core-libs-dev mailing list