explode()

Kevin Bourrillion kevinb at google.com
Thu Jan 24 17:36:04 PST 2013


On Thu, Jan 24, 2013 at 4:27 PM, Brian Goetz <brian.goetz at oracle.com> wrote:

So, you sort of came full circle to where we started, where we passed a
> Sink/Block/Consumer representing the downstream.  The big complaint against
> that was "What if I already have a Collection?  I have to iterate it
> myself?"
>
> I'm unwilling to lard Sink/Block/Consumer with these extra methods just to
> avoid the extra interface;


No, my point is that these methods are useful and natural and they belong
in Consumer/Whatever, regardless.  It's both convenient for the caller, and
gives implementors opportunities for greater efficiency. (I don't see how
this is full circle unless that exact idea was what was discussed, which it
doesn't sound like.)


they're not intrinsic enough to Sink/Block/Consumer to be worth the
> confusion.  Though we could have an interface that extends S/B/C that adds
> the extra methods.
>

I would disagree with such a child interface, because the two are the same
thing.



> Also, there's something stream-specific to the current Downstream; while
> the default for send(Stream) just delegates to forEach, this will fail if
> an element is mapped to an infinite stream.  However, a better
> implementation of send(Stream) could prevent this.  I want to leave that
> door open.
>

Okay, then why not leave that door open for all Consumers, as I propose?



> So, adding this all up:
>
>   interface Exploder<T, U> {
>     void explodeInto(T input, FragmentCollector<U> sink);
>   }
>
>   interface FragmentCollector<U> extends Sink<U> { // or better name
>     // with accept methods for array/stream/Iterable
>   }
>
>   <U> Stream<U> explode(Exploder<T,U>)
>
> Is this any better than the status quo?


No, I dislike both. :-)  And haven't yet heard any clear argument against
my suggestion.  I hope to hear others' opinions.



>
> On 1/24/2013 5:43 PM, Kevin Bourrillion wrote:
>
>> explode() is aptly named for what it did to my brain when I encountered
>> it. :-)
>>
>> A few things are adding up to make it impenetrable.
>>
>> 1. The vast majority of the Stream API, save the obvious exceptions like
>> forEach(), is solidly in the functional style. Collectors aren't really,
>> but as long as I use the prepackaged ones, it /feels/ fairly functional
>>
>> anyway. Now suddenly there's explode, which doesn't feel functional at
>> all. Instead, I need to think of the bit of code I provide to it as an
>> active participant in a pipeline. Things are fed to me, I feed things on
>> down the line. This makes it different, and different is automatically
>> confusing. This can't really be /corrected/, but seems worth nothing;
>>
>> maybe we can account for the difference somehow.
>>
>> 2. In attempting to learn it, I'm confronted with a type,
>> Stream.Downstream<U>, which I won't have heard of before that moment,
>> and whose name reveals little.  Is there any particular reason that
>> Sink/Consumer, with its accept(T) method, should not also have "default"
>> methods implementing accept(Collection<T>) and accept(Stream<T>) and
>> accept(T[])?  I can't think of any; those sound just plain handy.  And
>> if we added those, would there be enough value in preserving Downstream
>> as an identically-signatured type?  We could dispense with it, as I've
>> done below.
>>
>> 3. Except sometimes there /is/ value in having a special type even if
>>
>> its signature is identical to another.  I suspect that a custom type
>> could help quite a bit in this case:
>>
>>     interface Exploder<T,R> {
>>        /**
>>         * Maps {code input} to zero or more instances of R, sending these
>>         * to {@code resultConsumer} to be included in the results of
>>         * {@link Stream#explode(Exploder)}.
>>         */
>>        void explode(T input, Consumer<R> resultConsumer);
>>     }
>>
>>
>> 4. Then there is the name "explode". It's... okay. "unpack"? Nah. It
>> seems maybe 40% possible that a great name is out there eluding us....
>>
>>
>>
>> --
>> Kevin Bourrillion | Java Librarian | Google, Inc. |kevinb at google.com
>> <mailto:kevinb at google.com>
>>
>


-- 
Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at google.com


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