----- Mail original -----
> De: "Stuart Marks" <stuart.ma...@oracle.com>
> À: "Remi Forax" <fo...@univ-mlv.fr>
> Cc: "core-libs-dev" <core-libs-dev@openjdk.java.net>
> Envoyé: Lundi 19 Avril 2021 17:41:11
> Objet: Re: ReversibleCollection proposal

> On 4/17/21 9:49 AM, Remi Forax wrote:
>> I think the analysis is spot on but I don't think the proposed solution is 
>> the
>> right one.
>> 
>> Introducing a new interface (two in this case) has a really huge cost and in
>> this case, i've trouble to see why i will want to write a method that takes a
>> ReversibleCollection as parameter, ReversibleCollection as a type does not 
>> seem
>> to be useful. About the cost of introducing a new collection interface, it
>> means that we also have to update all emptyXXX, singleXXX, uncheckedXXX with 
>> a
>> new interface, and that only for the JDK. Every libraries that proxy
>> collections has also to be updated to take care of this new type, otherwise 
>> the
>> integration with an application that uses this new type and the library is 
>> not
>> seamless anymore.
> 
> Hi Remi,
> 
> Thanks for looking at this. There are several issues intertwined here, so 
> let's
> try
> to break it down.
> 
> There are a bunch of factory methods emptyX, singletonX, etc. that give
> instances of
> particular types. As Tagir noted, List is a ReversibleCollection, so you can
> just
> use emptyList or List.of or whatever if you need an instance of
> ReversibleCollection. Also, SortedSet/NavigableSet are ReversibleSets, so if 
> you
> need an empty ReversibleSet, you can use Collections.emptyNavigableSet. 
> There's
> no
> singletonNavigableSet, but you could do
> 
>     Collections.unmodifiableNavigableSet(new TreeSet<>(List.of(x)))
> 
> which is a bit of a mouthful, but it's possible. (The fact that there's no
> Collections.singletonNavigableSet may mean this use case is so narrow that few
> people really needed it.)
> 
> As for the wrappers, synchronizedX and checkedX are mostly disused, so I don't
> see a
> need to provide those wrappers. Having unmodifiable RC and RS is probably
> useful, so
> I could see adding those. That's a certain amount of work, but not a 
> tremendous
> cost.

It's a shame that checkedX are not used more, at least in tests, because it's a 
simple way to know if a method will work with the new generics of Valhalla 
(it's the same semantics).

Anyway, the problem is not only for the JDK, but for all libraries like guava, 
eclipse collections, etc and also JVM languages that provides a collection 
interopt like Clojure or Scala. 

> 
>> All these methods can be introduced has default methods on the existing
>> collection interfaces, there is no need of a special interface (or two) for
>> that.
> 
> Clearly it's possible to get by without new interfaces. After all the
> collections
> framework has gotten by without them for 20+ years already. It's certainly
> possible
> to fill out the individual interfaces (List, Deque, Sorted/NavSet) and classes
> (LinkedHashSet, LinkedHashMap) with methods that are all similar to each 
> other,
> and
> that would be useful. Or as Peter Levart pointed out, we could push all of 
> them
> up
> to Collection and write the specs in a loose enough way to encompass even
> unordered
> collections.
> 
> Any of those alternatives (do nothing, add individual methods, add
> loosely-spec'd
> methods to Collection) are *possible* to do. However, I think you know how
> minimal
> we are with the JDK APIs, and we wouldn't have proposed new interfaces without
> good
> cause. Thus, I think introducing new *types* here is useful, for the following
> reasons.
> 
>  * There's a useful clump of semantics here, combined with sensible operations
>  that
> rely on those semantics. There are a lot of places in the spec where there is
> hedging of the form "if the collection has an ordering, then... otherwise the
> results are undefined". This is unnecessary in the context of a new type.
> Furthermore, the new operations fit well with the new types' semantics, with 
> no
> hedging necessary.

You can only say that a reversible collection has an ordering. But usually you 
want the opposite, all collections that have an ordering are a reversible 
collection. But while this can be true for the implementations inside the JDK 
that will never be true in Java because there all already collection 
implementations with an ordering which do not implement ReversibleCollection.

Sadly, this ship has sailed.
The spec will still have to say "if the collection has an ordering", otherwise 
the new semantics is not a backward compatible.

> 
>  * These semantics appear across a broad range of existing collection types 
> and
> implementations. It's quite valuable to have a type that unifies the common
> pieces
> of List, Deque, SortedSet, and LinkedHashSet into a single abstraction.

yes in term of documentation, but in Java, it also means that you can use that 
interface as a type.

For a List, a Deque or a Set, there are known algorithms that takes such type 
has parameter so it makes sense to have such type.
For a ReversibleCollection, i do not see many codes that will benefit taking a 
ReversibleCollection as parameter instead of using Collection.

> 
>  * It's useful to have a new type for parameters in APIs. There are times when
>  one
> wants to accept something like a List -or- a LinkedHashSet. Typically one 
> would
> accept a Collection and then write a spec with hedging as above ("the argument
> collection must have a defined ordering"). But this also allows bugs, for
> example if
> somebody accidentally passes a HashSet. Having ReversibleCollection helps this
> problem.

As i said above, "a collection must have an ordering" is not equivalent to a 
ReversibleCollection and it will never be.

> 
>  * It's useful to have a new type for return types in APIs. Consider
> LinkedHashMap's entrySet, keySet, and values views. While we clearly get by 
> with
> having these return Set or Collection today, we need a place to put the new
> methods.
> Either they go on Collection (and have extremely weak semantics) or we define
> new
> interfaces.

Even if you define a new interface, you can not change the return type of 
LinkedHashMap entrySet because it's not a backward compatible change. 
LinkedHashMap is not final so you have to update all subclasses of 
LinkedHashMap too.

> 
>  * It's a useful interface for new collection implementations. There are data
> structures that are ordered, double-ended, and reversible, but for which
> implementing List is too onerous. Supporting int indexes in various List APIs 
> is
> where stumbling blocks usually occur. I note that the LinkedHashMap view
> collections
> are examples of this that already exist in the prototype code. (Other
> possibilities
> might be something like SpinedBuffer or chunked linked lists.)

yes, but at the same time, we can introduce SpinedBuffer without 
ResersibleCollection.

> 
> In general, I agree that there should be strict criteria for introducing new
> interfaces into collections, but I think this proposal meets them.

I agree that having such interface at day one may have been a great addition to 
the collection framework.
But as a late addition, it's a split change, it's a change that requires every 
implementations of a collection with an ordering to update itself so it will 
play nicely with the future JDKs and codes developed to target those JDKs. 

> 
> s'marks

Rémi

Reply via email to