The introduction of Sequenced collections is not a source compatible change

Ethan McCue ethan at mccue.dev
Fri May 5 04:50:56 UTC 2023


For those who are tracking but didn't click through to find it, here was
the writeup of the compatibility analysis for sequenced collections as of
9/20/22.

https://bugs.openjdk.org/secure/attachment/100811/compatibility-20220920.html

Bug page:

https://bugs.openjdk.org/browse/JDK-8266572




On Fri, May 5, 2023 at 12:08 AM Joseph D. Darcy <joe.darcy at oracle.com>
wrote:

> PS And as a general policy, over the releases we've done more to
> preserve source compatibility when possible for language changes.
>
> For example, there were many source compatibility breakages when
> "assert" was added as a keyword back in JDK 1.4; the current keyword
> management policies (https://openjdk.org/jeps/8223002), including
> contextual keywords (JLS §3.9) and hyphenated-keywords, mitigate the
> impact of analogous changes today.
>
> -Joe
>
> On 5/4/2023 7:47 PM, - wrote:
> > In addition, in the CSR of sequenced collection, it already
> > anticipated some other form of source incompatibility:
> > If a class implements List and Deque at the same time, the return type
> > of reversed() must extend both interfaces as well.
> >
> > This alone would be a greater source incompatibility than this type
> > interference already; however, both are binarily compatible:
> > Java doesn't care about generics at runtime, and for default
> > reversed() overrides, reversed ()Ljava/util/List; and reversed
> > ()Ljava/util/Deque; are distinct methods; code calling reversed via
> > List or Deque interfaces will get the reversed version of respective
> > interfaces, which are functionally correct as well.
> >
> > I personally would consider this type inference usage moot. It is same
> > as adding another method addAll(List<String>) when there is already
> > addAll(String[]): existing addAll(null) calls will break, but this is
> > not a valid argument against adding a List<String> variant of addAll.
> >
> > On Thu, May 4, 2023 at 9:38 PM Joseph D. Darcy <joe.darcy at oracle.com>
> wrote:
> >> A few comments on the general compatibility policy for the JDK.
> Compatibility is looked after by the Compatibility and Specification Review
> (CSR) process ( Compatibility & Specification Review). Summarizing the
> approach,
> >>
> >> The general compatibility policy for exported APIs implemented in the
> JDK is:
> >>
> >>      * Don't break binary compatibility (as defined in the Java
> Language Specification) without sufficient cause.
> >>      * Avoid introducing source incompatibilities.
> >>      * Manage behavioral compatibility changes.
> >>
> >> https://wiki.openjdk.org/display/csr/Main
> >>
> >> None of binary, source, and behavioral compatibly are absolutes and
> judgement is used to assess the cost/benefits of changes. For example,
> strict source compatibility would preclude, say, introducing new public
> types in the java.lang package since the implicit import of types in
> java.lang could conflict with a same-named type *-imported from another
> package.
> >>
> >> When a proposed change is estimated to be sufficiently disruptive, we
> conduct a corpus experiment to evaluate the impact on the change on many
> public Java libraries. Back in Project Coin in JDK 7, that basic approach
> was used to help quantify various language design choices and the
> infrastructure to run such experiments has been built-out in the subsequent
> releases.
> >>
> >> HTH,
> >>
> >> -Joe
> >> CSR Group Lead
> >>
> >> On 5/4/2023 6:32 AM, Ethan McCue wrote:
> >>
> >> I guess this a good time to ask, ignoring the benefit part of a cost
> benefit analysis, what mechanisms do we have to measure the number of
> codebases relying on type inference this will break?
> >>
> >> Iirc Adoptium built/ran the unit tests of a bunch of public repos, but
> it's also a bit shocking if the jtreg suite had nothing for this.
> >>
> >> On Thu, May 4, 2023, 9:27 AM Raffaello Giulietti <
> raffaello.giulietti at oracle.com> wrote:
> >>> Without changing the semantics at all, you could also write
> >>>
> >>>          final List<Collection<String>> list =
> >>> Stream.<Collection<String>>of(nestedDequeue, nestedList).toList();
> >>>
> >>> to "help" type inference.
> >>>
> >>>
> >>>
> >>>
> >>> On 2023-05-03 15:12, forax at univ-mlv.fr wrote:
> >>>> Another example sent to me by a fellow French guy,
> >>>>
> >>>>       final Deque<String> nestedDequeue = new ArrayDeque<>();
> >>>>       nestedDequeue.addFirst("C");
> >>>>       nestedDequeue.addFirst("B");
> >>>>       nestedDequeue.addFirst("A");
> >>>>
> >>>>       final List<String> nestedList = new ArrayList<>();
> >>>>       nestedList.add("D");
> >>>>       nestedList.add("E");
> >>>>       nestedList.add("F");
> >>>>
> >>>>       final List<Collection<String>> list = Stream.of(nestedDequeue,
> nestedList).toList();
> >>>>
> >>>> This one is cool because no 'var' is involved and using
> collect(Collectors.toList()) instead of toList() solves the inference
> problem.
> >>>>
> >>>> Rémi
> >>>>
> >>>> ----- Original Message -----
> >>>>> From: "Stuart Marks" <stuart.marks at oracle.com>
> >>>>> To: "Remi Forax" <forax at univ-mlv.fr>
> >>>>> Cc: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> >>>>> Sent: Tuesday, May 2, 2023 2:44:28 AM
> >>>>> Subject: Re: The introduction of Sequenced collections is not a
> source compatible change
> >>>>> Hi Rémi,
> >>>>>
> >>>>> Thanks for trying out the latest build!
> >>>>>
> >>>>> I'll make sure this gets mentioned in the release note for Sequenced
> >>>>> Collections.
> >>>>> We'll also raise this issue when we talk about this feature in the
> Quality
> >>>>> Outreach
> >>>>> program.
> >>>>>
> >>>>> s'marks
> >>>>>
> >>>>> On 4/29/23 3:46 AM, Remi Forax wrote:
> >>>>>> I've several repositories that now fails to compile with the latest
> jdk21, which
> >>>>>> introduces sequence collections.
> >>>>>>
> >>>>>> The introduction of a common supertype to existing collections is
> *not* a source
> >>>>>> compatible change because of type inference.
> >>>>>>
> >>>>>> Here is a simplified example:
> >>>>>>
> >>>>>>      public static void m(List<Supplier<? extends Map<String,
> String>>> factories) {
> >>>>>>      }
> >>>>>>
> >>>>>>      public static void main(String[] args) {
> >>>>>>        Supplier<LinkedHashMap<String,String>> supplier1 =
> LinkedHashMap::new;
> >>>>>>        Supplier<SortedMap<String,String>> supplier2 = TreeMap::new;
> >>>>>>        var factories = List.of(supplier1, supplier2);
> >>>>>>        m(factories);
> >>>>>>      }
> >>>>>>
> >>>>>>
> >>>>>> This example compiles fine with Java 20 but report an error with
> Java 21:
> >>>>>>      SequencedCollectionBug.java:28: error: method m in class
> SequencedCollectionBug
> >>>>>>      cannot be applied to given types;
> >>>>>>        m(factories);
> >>>>>>        ^
> >>>>>>      required: List<Supplier<? extends Map<String,String>>>
> >>>>>>      found:    List<Supplier<? extends SequencedMap<String,String>>>
> >>>>>>      reason: argument mismatch; List<Supplier<? extends
> SequencedMap<String,String>>>
> >>>>>>      cannot be converted to List<Supplier<? extends
> Map<String,String>>>
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> Apart from the example above, most of the failures I see are in the
> unit tests
> >>>>>> provided to the students, because we are using a lot of 'var' in
> them so they
> >>>>>> work whatever the name of the types chosen by the students.
> >>>>>>
> >>>>>> Discussing with a colleague, we also believe that this bug is not
> limited to
> >>>>>> Java, existing Kotlin codes will also fail to compile due to this
> bug.
> >>>>>>
> >>>>>> Regards,
> >>>>>> Rémi
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20230505/b80124fd/attachment-0001.htm>


More information about the core-libs-dev mailing list