Into

Jim Mayer jim at pentastich.org
Mon Dec 24 18:09:29 PST 2012


Doug,

Couldn't a syntax something like the one Brian used in the kick off message
of this thread be used to address the issues you raised without losing the
fluidity of the API?.  Brian's example looked something like
Stream.tabulate(Collector).

Wouldn't a method on Stream<T> like:

    <S> S tabulate(Collector<T,S>)

where Collector looked like:

    interface Collector<T,S> {
        S collect(Stream<S> stream);
    }

work?  It would fit with the fluid style and would keep the Collections
framework out of the Streams API.

It would need the "clever" trick that "into" uses to pass the stream to the
Collector, but isn't that just some syntactic sugar to keep the fluid API?
On the other hand, it would move the "magic" out of "into" and into the
"Collector" implementation (which should know more about the result type).

Some interesting methods might be:

    Collections.toList() -- picks a convenient type
    Collections.toSet () -- picks a convenient type
    ArrayList.collector() -- specify a concrete type
    etc.

I have not been following the design closely enough to know whether you
would want parallel and sequential forms of the interface.

Jim
On Dec 23, 2012 7:51 AM, "Doug Lea" <dl at cs.oswego.edu> wrote:

> On 12/22/12 17:15, Brian Goetz wrote:
>
>  (One thing I don't love is that they bring List/Map back into the API --
>> after
>> all the work we did in groupBy to move it out.  But this is more
>> superficial
>> than what groupBy/reduceBy did, so I'm probably OK with this --
>> especially if
>> they are just sugar.)
>>
>
> My (long-standing :-) concern is the potential bug-tail
> of methods that introduce one more level of indirection on the
> already intractable binary-method problem. Method into()
> is asked to automagically resolve any mismatches between
> properties of the source and of the destination;
> where the properties mainly include ordered and parallel,
> but also keyed, sorted, indexed, random-access.
> The Collections framework is not especially good at helping you
> out here. One possibility for reducing complexity is to
> limit the number of cases, via toList, toSet, etc and allow
> the implementation to rely on particular properties of the
> internally chosen destination classes.
> This is not very exciting, but it also does not rule
> out doing something more ambitious later.
>
> Another strategy (a variant of one discussed before)
> for collapsing one side of the binary method problem
> would be to somehow require that concrete
> Collection/Map classes support a stream-based constructor.
> This encounters a couple of snags though: (1) We can't
> require or default-define constructors, so would have
> to live with say void buildFromStream(Stream x)
> (default: if !empty die else sequential-forEach-add).
> (2) Usages lose the fluency look-and-feel, which bothers
> some people a lot: Usages must declare and use the
> destination in a separate statement than the pipleline
> expression.
>
> I'd probably prefer this approach, in part because it
> does fully remove collections from the stream framework
> (by adding stream support to the collections framework,
> which we must do anyway.). But I realize that
> the fluent-API expectations for streams make it an
> unpopular choice.
>
> Footnote: Recall that Scala deals with the binary-method-problem
> aspects by encoding some of these constraints in the type system
> and resolving a match. Which is sorta cool but still produces
> anomalies.
>
> -Doug
>
>


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