Loose end: concat
Brian Goetz
brian.goetz at oracle.com
Thu May 23 14:57:33 PDT 2013
Same reason as into(Collection) -- these were the sole cases where the
arguments to stream methods were stateful objects; everything else is a
stateless recipe for how to transform a stream, but which does not
intrinsically mutate or consume any of its arguments.
This wasn't just a philosophical concern, though I do believe it makes
the API stronger. The problems showed up immediately in our testing
framework. Our testing framework is based on repeatable stream
transforms; we have an abstraction for "repeatable data source" (which
can deliver its data as a stream, parallel stream, iterator, or
spliterator), and tested stream operations using functions that
transformed a stream into a stream:
s -> s.map(i -> i*2)
With the repeatable data source, we were able to easily automate
comparison between dozens of different ways to express the same result,
such as:
source.stream().map(...).toArray()
source.parallelStream().map(...).toArray()
source.stream().map(...).collect(toList())
source.parallelStream().map(...).collect(toList())
source.stream().map(...).iterator()
... etc
When we saw how much trouble methods like into() and concat() were for
frameworks that want to build on the idea of "repeatable stream
source/transform", this was a big warning sign; our test framework could
not possibly be the only framework that would want to treat streams
functionally.
Secondarily, the value of fluency here is pretty limited, since its
likely that the other stream operation will be enough of a mouthful that
it will get "outlined" anyway.
So bottom line: with into(Collection) and concat(Stream) removed, any
function
s -> s.streamOp(nonInterferingLambda)
becomes a repeatable and stateless transform. No "except for ..."
caveats needed.
On 5/23/2013 4:15 PM, Joe Bowbeer wrote:
> Why was an instance method rejected? I can't recall.
>
> s = s1.concat(s2).concat(s3);
>
>
>
>
> On Thu, May 23, 2013 at 11:23 AM, Sam Pullara <spullara at gmail.com
> <mailto:spullara at gmail.com>> wrote:
>
> *Stream seems like the right place for them to me. It is certainly
> the second place I would look — first place would be as an instance
> method, but we've discussed that before.
>
> Sam
>
> On May 23, 2013, at 11:06 AM, Brian Goetz <brian.goetz at oracle.com
> <mailto:brian.goetz at oracle.com>> wrote:
>
> > I cleaned up concat() and wrote Int/Long/Double versions.
> (Fortunately, with the recent addition of Spliterator.OfPrimitive,
> the duplication quotient was much lower.)
> >
> > Currently these still live in Streams. Is that still the right
> place? The stream classes (Stream, IntStream, etc) seem a little
> wrong for them, but I can't quite put my finger on why.
> >
> > Specs:
> >
> > /**
> > * Creates a lazy concatenated {@code Stream} whose elements
> are all the
> > * elements of a first {@code Stream} succeeded by all the
> elements of the
> > * second {@code Stream}. The resulting stream is ordered if both
> > * of the input streams are ordered, and parallel if either of
> the input
> > * streams is parallel.
> > *
> > * @param <T> The type of stream elements
> > * @param a the first stream
> > * @param b the second stream to concatenate on to end of the
> first
> > * stream
> > * @return the concatenation of the two input streams
> > */
> > public static <T> Stream<T> concat(Stream<? extends T> a,
> Stream<? extends T> b) {
> >
> >
> > /**
> > * Creates a lazy concatenated {@code IntStream} whose
> elements are all the
> > * elements of a first {@code IntStream} succeeded by all the
> elements of the
> > * second {@code IntStream}. The resulting stream is ordered
> if both
> > * of the input streams are ordered, and parallel if either of
> the input
> > * streams is parallel.
> > *
> > * @param a the first stream
> > * @param b the second stream to concatenate on to end of the
> first stream
> > * @return the concatenation of the two streams
> > */
> > public static IntStream concat(IntStream a, IntStream b) {
> >
> >
> > (and similar for Long and Double).
> >
>
>
More information about the lambda-libs-spec-experts
mailing list