Into
Remi Forax
forax at univ-mlv.fr
Wed Dec 26 11:52:21 PST 2012
On 12/26/2012 07:38 PM, Brian Goetz wrote:
> Let's try to separate some things here.
>
> There's lots of defending of into() because it is (a) useful and (b)
> safe. That's all good. But let's see if we can think of these more
> as functional requirements than as mandating a specific API (whether
> one that happens to be already implemented, like into(), or the newly
> proposed ones like toEveryKindOfCollection().)
>
> Into as currently implemented has many negatives, including:
> - Adds conceptual and API surface area -- destinations have to
> implement Destination, the semantics of into are weird and unique to into
> - Will likely parallelize terribly
> - Doesn't provide the user enough control over how the into'ing is
> done (seq vs par, order-sensitive vs not)
>
> So let's step back and talk requirements.
>
> I think the only clear functional requirement is that it should be
> easy to accumulate the result of a stream into a collection or similar
> container. It should be easy to customize what kind of collection,
> but also easy to say "give me a reasonable default." Additionally, the
> performance characteristics should be transparent; users should be
> able to figure out what's going to happen.
>
> There are lots of other nice-to-haves, such as:
> - Minimize impact on Collection implementations
> - Minimize magic/guessing about the user's intent
> - Support destinations that aren't collections
> - Minimize tight coupling of Stream API to existing Collection APIs
>
> The current into() fails on nearly all of these.
Brian, you confound the concept of into() with it's current implementation.
- Minimize impact on Collection implementations
=> fail because destination interface says that destination should
have a method add(Stream)
but this is not a requirement, destination can use already
existing add/addAll
- Minimize magic/guessing about the user's intent
=> fails, due to the implementation
- Support destinations that aren't collections
=> works
- Minimize tight coupling of Stream API to existing Collection APIs
=> part of the problem is point 1, the other part is that loosely
couple will come with a price for users
like requiring them to specify too many parameters for common
use cases.
for me the requirements are (in that order)
- support classical collections in a way that is always thread safe
- support destination that are not collections
- minimize coupling with Collection API
if you want to compare your tabulator with into, into has to be
correctly specified,
I think, it should be something like this:
into(Supplier<Destination<T>> supplier)
with the interface Destination defined like this
interface Destination<T, D extends Destination<? extends T, D>> {
boolean add(T element);
boolean addAll(D destination);
}
example of usages:
stream.into(ArrayList::new); // with Collection<E> implements
Destination<E, Collection<E>>
with that, I see your tabulator as a more fine grain API that into() but
that requires users to send more information.
Rémi
More information about the lambda-libs-spec-observers
mailing list