Whither FlatMapper?

Brian Goetz brian.goetz at oracle.com
Mon Apr 8 15:33:52 PDT 2013


OK, let me be more explicit.

We currently have:

Stream:
     <R> Stream<R> flatMap(Function<? super T, ? extends Stream<? 
extends R>> mapper);
     <R> Stream<R> flatMap(FlatMapper<? super T, R> mapper);
     IntStream flatMapToInt(FlatMapper.ToInt<? super T> mapper);
     LongStream flatMapToLong(FlatMapper.ToLong<? super T> mapper);
     DoubleStream flatMapToDouble(FlatMapper.ToDouble<? super T> mapper);

Plus two forms in each of {Int,Long,Double}Stream:

     DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper);
     DoubleStream flatMap(FlatMapper.OfDoubleToDouble mapper);

Plus seven variants of FlatMapper:
     FlatMapper
     FlatMapper.Of{Int,Long,Double}
     FlatMapper.OfXToX for X={Int,Long,Double}

The proposal was to:
  - Keep the first form under Stream
  - Keep the first form under each of {Int,Long,Double}Stream
  - Remove the other forms
  - Remove all FlatMapper SAM variants
  - Add back 3 new Obj-to-int specializations to Stream:
     <R> Stream<R> flatMapToXxx(Function<T, XxxStream> mapper);

Then *all* the flatMap forms would take some form of element -> Stream 
function.

The motivation is: no one can understand the (element, Consumer) 
versions of these, and, even when explained, most people can't 
understand why they would ever not use the T->Stream<U> form, and the 
(element, Consumer) forms generate a lot of API surface area (including 
7 classes in java.util.stream).

The downside is that the T->STream<U> form *is* intrinsically slower, 
though we've made pretty big progress lately on stream startup cost and 
anticipate making more.

The objection to the proposal, coming from a few advanced users, is: 
"but, now that I *finally* figured out how the (element, Consumer) 
versions work, I realize they're faster, so I don't want to give them 
up."  (Note that we can still always add them later.)

The fallback position is to keep the methods as is, but drop the 
FlatMapper name, and instead fall back to BiConsumer<Element, 
Consumer<Element>>.  Frankly, I think that makes the advanced forms even 
harder to understand.

I still like the original proposal.




On 4/8/2013 6:09 PM, Remi Forax wrote:
> On 04/08/2013 10:05 PM, Brian Goetz wrote:
>> A slight correction: if we remove the flatMap(FlatMapper), there is no
>> fluent form that is as efficient as the removed form that accepts (T,
>> Consumer<T>), since there's no other way to get your hands on the
>> downstream Sink.  (Not that this dampens my enthusiasm for removing it
>> much.)
>>
>> For the truly diffident, a middle ground does exist: remove FlatMapper
>> and its six brothers as a named SAM, and replace it with BiConsumer<T,
>> Consumer<T>>, leaving both forms of flatMap methods in place:
>>   flatMap(Function<T,STream<U>>)
>>   flapMap(BiConsumer<T, Consumer<U>>)
>>
>
> me trying to understand ...
> we don't have more forms due to the primitive specialization ?
>
>> The main advantage being that the package javadoc is not polluted by
>> seven forms of FlatMapper.
>
> Rémi
>
>>
>> On 4/8/2013 3:27 PM, Doug Lea wrote:
>>> On 04/07/13 19:01, Sam Pullara wrote:
>>>> I'm a big fan of the current FlatMapper stuff that takes a Consumer.
>>>> Much more
>>>> efficient and straightforward when you don't have a stream or
>>>> collection to just
>>>> return. Here is some code that uses 3 of them for good effect:
>>>
>>> I think the main issue is whether, given the user reactions so far, we
>>> should insist on people using a generally better but non-obvious
>>> approach to flat-mapping. Considering that anyone *could* write their
>>> own
>>> FlatMappers layered on top of existing functionality (we could
>>> even show how to do it as a code example somewhere), I'm with
>>> Brian on this: give people the obvious forms in the API. People
>>> who are most likely to use it are the least likely to be obsessive
>>> about its performance. And when they are, they can learn about
>>> alternatives.
>>>
>>> -Doug
>>>
>


More information about the lambda-libs-spec-observers mailing list