----- Mail original -----
> De: "Brian Goetz" <brian.go...@oracle.com>
> À: "Tagir Valeev" <amae...@gmail.com>
> Cc: "Remi Forax" <fo...@univ-mlv.fr>, "Stuart Marks" 
> <sma...@openjdk.java.net>, "core-libs-dev"
> <core-libs-dev@openjdk.java.net>
> Envoyé: Mercredi 4 Novembre 2020 18:58:59
> Objet: Re: RFR: 8180352: Add Stream.toList() method

>> As for nullity topic, I really welcome that the proposed toList() is
>> null-tolerant but it worth mentioning that existing terminal
>> operations like findFirst(), findAny(), min() and max() are already
>> null-hostile.
> The min() and max() methods are not null hostile.  If you pass a
> null-friendly comparator (such as returned by the `nullsFirst()` and
> `nullsLast()` comparator combinators), nulls are not a problem.  The
> null hostility comes not from streams, but from the behaviors that
> clients pass to stream methods, whether they be min() or max() or
> map().  If the behaviors passed to _any_ stream method are null-hostile,
> then (usually) so will be that stream pipeline.  But this is something
> entirely under the control of the user; users should ensure that their
> domain and the behaviors that operate on that domain are consistent.
> 
> What we're talking about is what _streams_ should do.  Streams should
> not gratutiously narrow the domain.  Since `toList()` will be built into
> streams, we have to define this clearly, and there's no justification
> for making this method null-hostile.  The arguments made so far that
> toList() should somehow be null-hostile appear to be nothing more than
> weak wrappers around "I hate nulls, so let's make new methods
> null-hostile."
> 
> Remi say:
> 
>> You know that you can not change the implementation of
>> Collectors.toList(), and you also know that if there is a method
>> Stream.toList(), people will replace the calls to
>> .collect(Collectors.toList()) by a call to Stream.toList() for the
>> very same reason but you want the semantics of Stream.toList() to be
>> different from the semantics of Collectors.toList().
> 
> This is what I call a "for consistency" argument.  Now, we all know that
> consistency is a good starting point, but almost invariably, when
> someone says "you should do X because for consistency with Y", that "for
> consistency" argument turns out to be little more than a thin wrapper
> around "I prefer Y, and I found a precedent for it." Yes, people will be
> tempted to make this assumption -- at first. (And most of the time, that
> will be fine -- the most common thing people do after collecting to a
> list is iterate the list.)   But it is a complete inversion to say that
> the built-in method must be consistent with any given existing
> Collector, even if that collector has a similar name.  The built-in
> method should provide sensible default to-list behavior, and if you want
> _any other_ to-list behavior -- a mutable list, a different type of
> list, a null-hostile list, a list that drops prime-numbered elements,
> whatever -- you use the more general tool, which is collect(), which
> lets you do whatever you want, and comes with a variety of
> pre-configured options.  And this is the most sensible default behavior
> for a built-in to-list operation.

As i said since, i can live with only one method toList() instead of two 
(toList() and toUnmodifiableList()), as you said this requires to provide a 
good default.
Obviously i still disagree with you about what the good default is.

This morning i was thinking about the symmetry between stream.toList() and 
stream.toArray(), there are two variants of toarray, toArray() and 
toArray(IntFunction<A[]>),
the second variant let you choose as a user which implementation of array you 
want.

I wonder if we should not do the same with toList(), having toList() to be 
equivalent to collect(Collectors.toUnmodifiableList()) and 
toList(IntFunction<List<E>>) allowing to use a null friendly List 
implementation like ArrayList. 

> 
> firstFirst/findAny are indeed sad corner cases, because we didn't have a
> good way of representing "maybe absent nullable value."  (If that case
> were more important, we might have done more work to support it.)  But I
> think it would be a poor move to try and extrapolate from this behavior;
> this behavior is merely a hostage to circumstance.

Rémi

Reply via email to