----- Mail original -----
> De: "Brian Goetz" <brian.go...@oracle.com>
> À: "Remi Forax" <fo...@univ-mlv.fr>, "Stuart Marks" <sma...@openjdk.java.net>
> Cc: "core-libs-dev" <core-libs-dev@openjdk.java.net>
> Envoyé: Mardi 3 Novembre 2020 19:02:37
> Objet: Re: RFR: 8180352: Add Stream.toList() method

>>> This change introduces a new terminal operation on Stream. This looks like a
>>> convenience method for Stream.collect(Collectors.toList()) or
>>> Stream.collect(Collectors.toUnmodifiableList()), but it's not. Having this
>>> method directly on Stream enables it to do what can't easily by done by a
>>> Collector. In particular, it allows the stream to deposit results directly 
>>> into
>>> a destination array (even in parallel) and have this array be wrapped in an
>>> unmodifiable List without copying.
>>>
>>> Hi Stuart,
>>> I'm Okay with the idea of having a method toList() on Stream but really 
>>> dislike
>>> the proposed semantics because tit is neither stream.collect(toList()) nor
>>> stream.collect(toUnmodifiableList()) but something in between.
>>>
>>> It's true that a Stream support nulls, we want people to be able map() with 
>>> a
>>> method that returns null and then filter out the nulls (even if using 
>>> flatMap
>>> for this case is usually a better idea),
>>> but it doesn't mean that all methods of the Stream interface has to support
>>> nulls, the original idea was more to allow nulls to flow in the stream 
>>> because
>>> at some point they will be removed before being stored in a collection.
> 
> Uhm ... no and no.
> 
> It does mean that all methods of the stream interface have to support
> nulls.  Streams are null tolerant.  Because ...
> 
> The original idea was not "the nulls can be removed later."  The
> original idea was "Streams are plumbing, they pass values through
> pipelines, to user-specified lambdas, into arrays, etc, and the stream
> plumbing should not have an opinion on the values that are flowing
> through."   And this was the right choice.

A stream is computation, so i agree that letting nulls to flow is the right 
call.
So i stand corrected on that point.

> 
> There is no value in making users remember which stream methods are
> null-hostile and which are null-tolerant; this is just more accidental
> complexity. 

I think that ship has sailed a long ago.
Some collectors are null hostile, some are not.
You can make a point that a Collector is technically not the Stream API per se.

[...]

Let's take a step back,
if we introduce a method toList() on Stream it will be used a lot, i mean 
really a lot, to the point where people will change the code from 
stream.collect(Collectors.toList()) to use stream.toList() instead.

Because of that, i don't think we even have the choice of the semantics for 
Stream.toList(), it has to be the same as stream.collect(Collectors.toList()).

So you are right that toList() can not be null hostile because 
Collectors.toList() is not null hostile.

But it can not be immutable too, for the same reason.

> Stuart made the right choice here.

I would say half of the right choices, null hostile: right, immutable: wrong :)

And if we at some point introduce a method toImmutableList() on Stream, it will 
have to be null hostile.

Rémi

Reply via email to