Hi Aaron, > De: "Aaron Scott-Boddendijk" <tal...@gmail.com> > À: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "Brian Goetz" <brian.go...@oracle.com>, "Stuart Marks" > <sma...@openjdk.java.net>, "core-libs-dev" <core-libs-dev@openjdk.java.net> > Envoyé: Mardi 3 Novembre 2020 21:59:37 > Objet: Re: RFR: 8180352: Add Stream.toList() method
> >>> But it can not be immutable too, for the same reason. > >> Nope. The spec of toList() very clearly says: no guarantees as to the type, > >> mutability, serializability, etc etc of the returned list. That doesn't > >> mean > >> that every method returning a List added to the JDK after > >> Collectors::toList > >> must similarly disavow all such guarantees. > >> (In fact, we would be entirely justified to change the behavior of > >> Collectors::toList tomorrow, to match the proposed Stream::toList; the > >> spec was > >> crafted to preserve this option. We probably won't, because there are too > >> many > >> programmers who refuse to read the specification, and have baked in the > >> assumption that it returns an ArrayList, and this would likely just be > >> picking > >> a fight for little good reason, regardless of who is right.) > >I don't understand your argument. >>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(). > Surely, taking that position, List.of(...) should not have produced an > unmodifiable list since many combinations of creating Lists would not have > produced unmodifiable lists. The problem is that people will see stream.toList() as a shorcut for stream.collect(Collectors.toList()), i've not seen my student thinking that List.of() is a shortcut for creating an ArrayList with some elements, but maybe it's because we introduce ArrayList later compared to List.of(...). > In all of the teams I've worked with, through many Java version transitions > (and > 3rdparty library version transitions), dealing with the selective adoption of > new APIs is nothing new. > This case is no different, developers will need to identify the cases in which > they can accept the list as unmodifiable and replace those uses of > Collectors.toList() and Collectors.toUnmodifiableList(). We have Collectors.toList() and Collectors.toUnmodifiableList(), would it make more sense to have stream.toList() and stream.toUnmodifiableList() instead of having stream.toList() that behave half way in betwen the semantics of Collectors.toList() and Collectors.toUnmodifiableList(). > And static-analysis will be able to propose some of those replacements for us. I believe that a tool able to suggest to use Collectors.toUnmodifiableList() instead of Collectors.toList() will rely one a global interprocedural static analysis, so such analysis will be invalid once you will update one of your dependency. > Does this mean it's more complex than a text-replace, sure. Will there be > mistakes, sure. But are there benefits to the immutability of the API result? > I > suggest that's pretty hard to debate against given the risk of a mistake is an > exception rather than bad data outcomes. You want immutability/unmodifiability over the cost of people miss mis-using the API. I think it's a sin as bad as me want stream.toList() to return a null hostile List :) As Brain implies, Java is a blue collar language, we should not forget it, whatever we think about null or immutability. And I said above perhaps we should not discussed about adding a method Stream.toList() but a method Stream.toUnmodifiableList(). > Please don't blunt the tool to make it safer for children. > -- > Aaron Scott-Boddendijk Rémi > On Wed, Nov 4, 2020 at 9:30 AM < [ mailto:fo...@univ-mlv.fr | > fo...@univ-mlv.fr > ] > wrote: >> > De: "Brian Goetz" < [ mailto:brian.go...@oracle.com | >> > brian.go...@oracle.com ] > >> > À: "Remi Forax" < [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] > >>> Cc: "Stuart Marks" < [ mailto:sma...@openjdk.java.net | >>> sma...@openjdk.java.net >> > ] >, "core-libs-dev" >> > < [ mailto:core-libs-dev@openjdk.java.net | core-libs-dev@openjdk.java.net >> > ] > >> > Envoyé: Mardi 3 Novembre 2020 20:54:57 >> > Objet: Re: RFR: 8180352: Add Stream.toList() method >> >>> 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. >> > Yes, and this is no mere "technical argument". A Collector is a collection >> > of >> > behaviors, governed by its own spec. The behaviors passed to stream >> > operations, >> > whether they be lambdas passed by the user (`.map(x -> >> > x.hopeXIsntNull())`) or >> > collector objects or comparators, are under the control of the user, and >> > it is >> > the user's responsibility to pass behaviors which are compatible with the >> > data >> > domain -- which the user knows and the streams implementation cannot know. >> >> 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()). >> > This doesn't remotely follow. (And, if it did, I would likely not even >> > support >> > this RFE.) >> It seems you had an issue when replying to my mail, there is a paragraph >> before >> "Because" >> > 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. >> > The spec of Collectors::toList was crafted to disavow pretty much anything >> > other >> > than List-hood, in part in anticipation of this addition. >> >> But it can not be immutable too, for the same reason. >> > Nope. The spec of toList() very clearly says: no guarantees as to the type, >> > mutability, serializability, etc etc of the returned list. That doesn't >> > mean >> > that every method returning a List added to the JDK after >> > Collectors::toList >> > must similarly disavow all such guarantees. >> > (In fact, we would be entirely justified to change the behavior of >> > Collectors::toList tomorrow, to match the proposed Stream::toList; the >> > spec was >> > crafted to preserve this option. We probably won't, because there are too >> > many >> > programmers who refuse to read the specification, and have baked in the >> > assumption that it returns an ArrayList, and this would likely just be >> > picking >> > a fight for little good reason, regardless of who is right.) >> I don't understand your argument. >> 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(). >> Rémi