Hi Joe and Stuart,

Given the inconsistencies mentioned, I see how this change may not be worth the 
hassle, so I’ll drop it. I appreciate the thoughtful responses to explain your 
reasoning. 

Thanks!
Ryan 


> On Jul 7, 2023, at 4:21 PM, Stuart Marks <stuart.ma...@oracle.com> wrote:
> 
> Hi Ryan,
> 
> Thanks for trying out JDK 21 early access.
> 
> The issue you raise is indeed an inconsistency, but it's not clear which way 
> it should be resolved, or even whether it needs to be resolved, as the 
> consequences are quite minor.
> 
> Specifically, when the Sequenced Collections JEP was integrated, it included 
> these changes (edited for brevity):
> 
> - public interface List<E> extends Collection<E> {
> + public interface List<E> extends SequencedCollection<E> {
> 
> - public interface SortedSet<E> extends Set<E> {
> + public interface SortedSet<E> extends Set<E>, SequencedSet<E> {
> 
> As you observed, on List, SequencedCollection has replaced Collection, but on 
> SortedSet, SequencedSet was added alongside Set. Which way is correct? Should 
> SequencedCollection have been added to List, instead of replacing Collection? 
> Or on SortedSet, should SequencedSet have replaced Set instead of simply 
> being added?
> 
> (I have to admit my first inclination was that the SortedSet change was a 
> mistake, and that SequencedSet ought to have replaced Set. I think the reason 
> it turned out the way it did was that, my earliest prototype, before I 
> published anything, had a single interface OrderedCollection. This was 
> retrofitted onto SortedSet as
> 
>    public interface SortedSet<E> extends Set<E>, OrderedCollection<E> {
> 
> Only later did I decide to add OrderedSet, and so I changed the declaration to
> 
>    public interface SortedSet<E> extends Set<E>, OrderedSet<E> {
> 
> and I didn't notice that the interfaces could be minimized. And of course 
> there were a couple rounds of renaming subsequent to this.)
> 
> In any case, this inconsistency is of little consequence, as the members 
> available to users of the interfaces in question are the same regardless of 
> the way the interfaces are declared. This is true from both a source and 
> binary compatibility standpoint.
> 
> Joe's point about compatibility is that even though such changes are 
> *visible* to reflective code, they aren't *incompatible*. There are many 
> compatible changes possible, such as moving the declaration of a method 
> upward in the hierarchy. From the standpoint of reflection, that method may 
> appear to have been removed from some interface; but that doesn't mean it's 
> incompatible. Reflective code needs to be adjusted to take such things into 
> account. The presence or absence of Collection as a superinterface of List is 
> a similar case.
> 
> Perhaps in some sense the JDK itself ought to be more consistent about this. 
> We have for example this:
> 
>    class HashSet extends AbstractSet implements Set, Cloneable, Serializable
> 
> but also this:
> 
>    class EnumSet extends AbstractSet implements Cloneable, Serializable
> 
> (That is, EnumSet is "missing" Set.)
> 
> Questions about this have been asked on Stack Overflow, and various answers 
> there have made up a rationale about the possibly-redundant interfaces being 
> included explicitly because it expresses intent more clearly, or some such. 
> My own guess is that nobody has paid much attention to this issue because 
> resolving it one way or another hardly makes any practical difference.
> 
> s'marks
> 
>> On 7/7/23 7:25 AM, Ryan Ernst wrote:
>> Thanks for laying out your thinking, Joe. I will watch your talks.
>> If I understood your response correctly, you are ok making such a change, 
>> especially since it is semantically equivalent? If that’s the case, is JDK 
>> 21 past the point of feature release, or should the change target only 22? 
>> It doesn’t matter much to me, but I thought since SequencedCollection is 
>> added in 21 it would be good to “fix” this there so as to avoid a gap in 
>> behavior.
>>>> On Jun 30, 2023, at 6:13 PM, Joseph D. Darcy <joe.da...@oracle.com> wrote:
>>> 
>>> Hi Ryan,
>>> 
>>> Apropos of this discussion, I happened to recently give a talk to the JCP 
>>> that in part covered behavioral compatibility in the JDK:
>>> 
>>> https://jcp.org/aboutJava/communityprocess/ec-public/materials/2023-06-13/JCP-EC-Public-Agenda-June-2023.html
>>> https://jcp.org/aboutJava/communityprocess/ec-public/materials/2023-06-13/Contributing_to_OpenJDK_2023_04_12.pdf
>>> 
>>> There are many observable details of the JDK implementation, including 
>>> reflective details, timing, etc. there are _not_ part of the interfaces 
>>> users should rely on.
>>> 
>>> My current evaluation here is that it would set an unfortunate precedent to 
>>> preclude making the sort of source changes in questions because of 
>>> (potential) compatibility concerns in reflective modeling, especially in a 
>>> feature release. (IMO, there is a stronger argument for not making such a 
>>> change in an update release, but even there as the change is a semantically 
>>> equivalent refactoring, I think it is generally fine.)
>>> 
>>> HTH,
>>> 
>>> -Joe
>>> 
>>>> On 6/29/2023 11:30 AM, Ryan Ernst wrote:
>>>> Thanks for replying, Joe. First, let me reiterate, we fully admit
>>>> there was a bug in painless, we stopped short in walking the class
>>>> hierarchy. There is no bug in the SequencedCollection hierarchy. But I
>>>> do think there is an inconsistency.
>>>> 
>>>>> The two definition are semantically equivalent
>>>>> ...
>>>>> The JDK 22 javadoc for List shows:
>>>>>> All Superinterfaces:
>>>>>>     Collection<E>, Iterable<E>, SequencedCollection<E>
>>>> While that is true, in practice the reflection API does not give the
>>>> same collapsed view that javadocs do. Calling getInterfaces() on a
>>>> class only returns direct super interfaces, so
>>>> List.class.getInterfaces() no longer returns Collection.class in JDK
>>>> 21.
>>>> 
>>>> The inconsistency I see is that SortedSet.class.getInterfaces() *does*
>>>> still return Set.class. Was that intentional? It seems like either
>>>> SortedSet does not need to extend Set directly, or List should still
>>>> extend Collection directly. And doing the latter would provide an
>>>> extra layer of "compatibility" for applications that may look at
>>>> direct super interfaces, and be surprised that Collection disappeared
>>>> across JDK versions for List.
>>>> 
>>>>> On Wed, Jun 28, 2023 at 6:31 PM Joseph D. Darcy <joe.da...@oracle.com> 
>>>>> wrote:
>>>>> Hello,
>>>>> 
>>>>> What is Painless doing that would fail under
>>>>> 
>>>>>      List extends SequencedCollection ...
>>>>> 
>>>>> but work under
>>>>> 
>>>>>      List extends SequencedCollection, Collection ...
>>>>> 
>>>>> The two definition are semantically equivalent since SequencedCollection
>>>>> itself extends Collection.
>>>>> 
>>>>> The JDK 22 javadoc for List shows:
>>>>> 
>>>>>> All Superinterfaces:
>>>>>>     Collection<E>, Iterable<E>, SequencedCollection<E>
>>>>> There are certainly implementation artifacts concerning the details of
>>>>> how a type was declared that exposed via core reflection (for the
>>>>> javax.lang.model API during annotation processing at compile time), but
>>>>> it is a bug for third party programs to rely on such details.
>>>>> 
>>>>> HTH,
>>>>> 
>>>>> -Joe
>>>>> 
>>>>> On 6/27/2023 7:37 AM, Ryan Ernst wrote:
>>>>>> Hi core-libs-dev,
>>>>>> 
>>>>>> I know various threads have existed over the past few months on
>>>>>> SequencedCollection and its implications on compatibility. I wanted to
>>>>>> raise this semi-related issue we noticed recently after beginning
>>>>>> testing against Java 21.
>>>>>> 
>>>>>> Elasticsearch began testing against Java 21, and noticed a series of
>>>>>> failures in Painless (our builtin scripting language, which
>>>>>> dynamically compiles to bytecode). Most tests that used List failed to
>>>>>> compile, with several unknown methods (eg add). Painless builds a
>>>>>> hierarchy of classes it knows about for method resolution. This
>>>>>> hierarchy didn't know anything about SequencedCollection since we
>>>>>> currently compile against Java 17. Now, this was ultimately a bug in
>>>>>> Painless, because we knew there could be cases where we encounter
>>>>>> unknown classes in the hierarchy (eg a class which is not blessed to
>>>>>> be visible in the language). However, I think the reason we found that
>>>>>> bug (List extending from SequencedCollection) might still cause issues
>>>>>> for some.
>>>>>> 
>>>>>> While debugging the issue, something that struck me as interesting in
>>>>>> the SequencedCollection hierarchy is the difference between List and
>>>>>> SortedSet. Both of these classes were made to be compatible with
>>>>>> sequenced classes by adding the new classes as super interfaces,
>>>>>> SequencedCollection and SequencedSet, respectively. However, while
>>>>>> SortedSet was *added* as a super interface, List had its super
>>>>>> interface Collection *replaced* by SequencedCollection.
>>>>>> 
>>>>>> I don't know enough about the rampdown process to know if this is
>>>>>> still fixable in Java 21. It is probably an extreme edge case that
>>>>>> doesn't matter, since eg instanceof Collection will still work in
>>>>>> existing code. But for consistency, it would seem better to maintain
>>>>>> Collection as a direct super interface of List. Is there any reason
>>>>>> such a change doesn't fit with the collections architecture going
>>>>>> forward?

Reply via email to