<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <div class="moz-cite-prefix">On 1/17/2025 5:49 PM, David Alayachew
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAA9v-_NKY77_Pu=FTUhNPXsuP84ykCs-Au03LDmx+2QT4ZPVew@mail.gmail.com">
      
      <p dir="ltr">It definitely helps.</p>
      <p dir="ltr">I guess my next question is, there is no bridge
        method, which is why this fails. Why not add a bridge method?
        What is stopping Java from doing this?</p>
    </blockquote>
    <p><br>
    </p>
    <p>The default response to the question "Should we fundamentally
      change how Java source files are compiled into class files?" is
      "No." ;-)<br>
      <br>
      Covariant returns "work" for instance methods for several reasons.
      Such behavior is expected from object-oriented type theory where
      it is sound for an overridden method to return a more specialized
      type in a subtype. Also, when presented with a single snapshot of
      the type hierarchy, as during compilation, it is relatively
      straightforward for the compiler to compute which bridge methods
      are needed, roughly look over the superclass and implemented
      interfaces for methods with the same name and set of arguments,
      but a different return type.</p>
    <p>Muddier on both accounts for how static methods would be handled
      by such a bridge method feature.<br>
    </p>
    <p>-Joe<br>
    </p>
    <p><br>
    </p>
    <blockquote type="cite" cite="mid:CAA9v-_NKY77_Pu=FTUhNPXsuP84ykCs-Au03LDmx+2QT4ZPVew@mail.gmail.com">
      <p dir="ltr">And to be clear, it is obvious to me that
        SewuencedSet.of is the right answer. I am just trying to
        understand the point you raised.</p>
      <br>
      <div class="gmail_quote gmail_quote_container">
        <div dir="ltr" class="gmail_attr">On Fri, Jan 17, 2025, 8:14 PM
          Joseph D. Darcy <<a href="mailto:joe.darcy@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">joe.darcy@oracle.com</a>>
          wrote:<br>
        </div>
        <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
          <div>
            <p><br>
            </p>
            <div>On 1/17/2025 5:00 PM, David Alayachew wrote:<br>
            </div>
            <blockquote type="cite">
              <div dir="auto">
                <p dir="ltr">Thanks for the corrections folks. I was
                  thinking from the perspective of LSP. I now see that
                  there is the performance perspective to consider too.</p>
                <p dir="ltr">Now that said, I don't understand your
                  comment Joe Darcy. Could you explain it in more
                  detail?</p>
              </div>
            </blockquote>
            <p>Say you compile your code against JDK 24 and use the
              1-argument Set.Of() method. For that call site, your class
              file will refer to a method using information akin to</p>
            <p>    "In the class java.util.Set, a method named "of" that
              *returns a java.util.Set* and take a java.lang.Object as
              an argument"</p>
            <p>(The generic information is basically erased in the class
              file, hence Set rather than Set<E> and Object rather
              than E.)</p>
            <p>If we were then in JDK 25 to replace in java.util.Set<br>
              <br>
                  static <E> Set<E> of(E e1){...}<br>
              <br>
              with</p>
            <p>    static <E> SequencedSet<E> of(E e1){...}</p>
            <p>when your class file ran against JDK 25, there would be
              no method</p>
            <p>    "In the class java.util.Set, a method named "of" that
              *returns a java.util.Set* and take a java.lang.Object as
              an argument"</p>
            <p>for your class to call and the linkage would fail.</p>
            <p>For static methods, the change is equivalent to removing
              a method and adding back a different, same-named method.</p>
            <p>HTH,<br>
            </p>
            <p>-Joe<br>
            </p>
            <p><br>
            </p>
            <blockquote type="cite">
              <div dir="auto">
                <p dir="ltr">My initial pick up of your comment is that,
                  the parameter types and the return types of a method
                  must match the types exactly between releases,
                  otherwise there are no bridge methods FOR STATIC
                  TYPES. But as for why, I don't understand.</p>
                <p dir="ltr">I know that static methods are not so much
                  inherited as they are just given as is (hence why
                  there is not really a static abstract method). But I
                  don't quite see the line connecting that with no
                  bridge methods for static. Maybe I don't understand
                  bridge methods well enough.</p>
              </div>
              <br>
              <div class="gmail_quote">
                <div dir="ltr" class="gmail_attr">On Fri, Jan 17, 2025,
                  12:32 PM Joseph D. Darcy <<a href="mailto:joe.darcy@oracle.com" rel="noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">joe.darcy@oracle.com</a>>
                  wrote:<br>
                </div>
                <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
                  <div>
                    <div>On 1/16/2025 11:26 PM, Rafael Winterhalter
                      wrote:<br>
                    </div>
                    <blockquote type="cite">
                      <div dir="ltr"> 
                        <div>Would it even be possible to change the
                          return types of Set.of(...) and Map.of(...)
                          without breaking binary compatibility?</div>
                      </div>
                    </blockquote>
                    <p><br>
                    </p>
                    <p>In short, no.</p>
                    <p>The methods in question are *static* methods.
                      Switching to covariant overrides with more precise
                      return types works for subclasses because of
                      bridge methods.</p>
                    <p>In a bit more detail, in a covariant override a
                      single method in the source code gets translated
                      into multiply methods in the class file.
                      References to methods in the class file use the
                      argument types and return type so if an old class
                      file refers to the previously declared
                      source-level return type, there is the bridge
                      method present to be linked to (for binary
                      compatibility) and then executed.<br>
                    </p>
                    <p>-Joe<br>
                    </p>
                    <p><br>
                    </p>
                    <blockquote type="cite">
                      <div dir="ltr">
                        <div><br>
                        </div>
                        <div>I also think that the randomization of
                          Set.of(...) and Map.of(...) is a good property
                          as it uncovers bugs early if one relies on
                          iteration order. This especially since those
                          methods are often used in tests where
                          production code would use a proper HashSet
                          which cannot guarantee iteration order for
                          good reasons. Exactly here I think the new
                          interfaces are a good addition as it uncovers
                          such misconceptions. If code relies on
                          insertion order, providing a Set.of(...) does
                          no longer compile, what is a good thing.<br>
                        </div>
                        <div><br>
                        </div>
                        <div>To me, adding SequencedSet.of(...) and
                          SequencedMap.of(...) sounds like the right
                          approach, with implementations similar to that
                          of Set.of(...) and Map.of(...). As for
                          megamorphism, I think the chance of encounter
                          at a call site is similar, as Set12 and SetN
                          from the Set interface are typically combined
                          with HashMap. As for a possible SequencedSet12
                          and SequencedSetN, I think they would normally
                          be seen with LinkedHashSet.</div>
                        <div><br>
                        </div>
                        <div>Best regards, Rafael<br>
                        </div>
                      </div>
                      <br>
                      <div class="gmail_quote">
                        <div dir="ltr" class="gmail_attr">Am Fr., 17.
                          Jan. 2025 um 00:36 Uhr schrieb David Alayachew
                          <<a href="mailto:davidalayachew@gmail.com" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">davidalayachew@gmail.com</a>>:<br>
                        </div>
                        <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                          <p dir="ltr">I should also add, the
                            documentation went out of their way to
                            specify that iteration order is unspecified.</p>
                          <p dir="ltr">Also, I see Rémi's comment, but
                            that's even more unconvincing to me.</p>
                          <p dir="ltr">Map.of has an upper limit of 10
                            entries, and Map.ofEntries has an upper
                            limit of that Java max file size limit
                            thing. You all know what I am talking about.</p>
                          <p dir="ltr">Point is, both of these static
                            factories were meant to be used on a small
                            number of entries. If it truly has just been
                            not done until now, then the bug database
                            will confirm that easily.</p>
                          <p dir="ltr">When I get back, I can check
                            myself.</p>
                          <br>
                          <div class="gmail_quote">
                            <div dir="ltr" class="gmail_attr">On Thu,
                              Jan 16, 2025, 6:25 PM David Alayachew <<a href="mailto:davidalayachew@gmail.com" rel="noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">davidalayachew@gmail.com</a>>
                              wrote:<br>
                            </div>
                            <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
                              <p dir="ltr">I guess let me ask the
                                obvious question.</p>
                              <p dir="ltr">Chesterton's fence -- why
                                wasn't this done before? I refuse to
                                believe that this idea wasn't thought up
                                years ago, which leads me to believe
                                there was a reason that it hasn't been
                                done.</p>
                              <p dir="ltr">Is there any way we can look
                                this up in the bug database or
                                something?</p>
                              <br>
                              <div class="gmail_quote">
                                <div dir="ltr" class="gmail_attr">On
                                  Thu, Jan 16, 2025, 2:28 PM Jens
                                  Lideström <<a href="mailto:jens@lidestrom.se" rel="noreferrer noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">jens@lidestrom.se</a>>
                                  wrote:<br>
                                </div>
                                <blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Having
                                  the result Map.of and Set.of preserve
                                  the insertion order would <br>
                                  often be convenient.<br>
                                  <br>
                                  More often than not programs iterate
                                  over the contents of a maps and <br>
                                  sets at some point. For example to
                                  present the values in a GUI, for <br>
                                  serialisation, or even for error
                                  printouts. In all those cases having a
                                  <br>
                                  fixed iteration order is much better
                                  than having a random iteration <br>
                                  order.<br>
                                  <br>
                                  Often it is even a subtle bug to have
                                  a random iteration order. For <br>
                                  example, I ran in to a situation where
                                  jdeps printed a error message <br>
                                  containing a list of modules. But the
                                  list was in a different order on <br>
                                  each run of the program! It took me a
                                  while to figure out that it was <br>
                                  actually the same list. A possible
                                  explanation is that jdeps is <br>
                                  implemented using Map.of or Set.of.<br>
                                  <br>
                                  Because of this I think I would be
                                  better if the most commonly used <br>
                                  standard collection factories produced
                                  collections with a fixed <br>
                                  iteration order.<br>
                                  <br>
                                  Guavas ImmutableMap and ImmutableSet
                                  also preserve insertion order.<br>
                                  <br>
                                  Regards,<br>
                                  Jens Lideström<br>
                                  <br>
                                  <br>
                                  On 2025-01-16 08:44, Remi Forax wrote:<br>
                                  <br>
                                  > -------------------------<br>
                                  > <br>
                                  >> From: "Rafael Winterhalter"
                                  <<a href="mailto:rafael.wth@gmail.com" rel="noreferrer noreferrer noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">rafael.wth@gmail.com</a>><br>
                                  >> To: "core-libs-dev" <<a href="mailto:core-libs-dev@openjdk.java.net" rel="noreferrer noreferrer noreferrer noreferrer noreferrer noreferrer" target="_blank" moz-do-not-send="true" class="moz-txt-link-freetext">core-libs-dev@openjdk.java.net</a>><br>
                                  >> Sent: Thursday, January 16,
                                  2025 8:13:17 AM<br>
                                  >> Subject: Factory methods for
                                  SequencedSet and SequencedMap<br>
                                  > <br>
                                  >> Hello,<br>
                                  > <br>
                                  > Hello,<br>
                                  > <br>
                                  >> I am happily taking
                                  SequencedSet and SequencedMap into
                                  use, but one <br>
                                  >> inconvenience I encounter is
                                  the lack of factory methods for the
                                  two.<br>
                                  >> In code where many (initial)
                                  collections have zero or one element
                                  (for <br>
                                  >> later aggregation), I now
                                  write Set.of()/Set.of(one) and <br>
                                  >> Map.of()/Map.of(key, value),
                                  as it makes the code shorter and more
                                  <br>
                                  >> readable. Those collections
                                  are of course implicitly sequenced,
                                  but <br>
                                  >> now I must make the variable
                                  type of the surrounding monad Set and
                                  <br>
                                  >> Map, and simply assume that a
                                  LinkedHashSet or LinkedHashMap is used
                                  <br>
                                  >> when a collection of more
                                  than one element is set, without
                                  requiring <br>
                                  >> the interface type. This does
                                  not require any type casting, as I
                                  rely <br>
                                  >> on the iteration order only,
                                  but the code loses some of its <br>
                                  >> expressiveness.<br>
                                  >> I did not find any discussion
                                  around introducing factories for <br>
                                  >> SequencedSet.of(...) and
                                  SequencedMap.of(...), similar to those
                                  that <br>
                                  >> exist in the Set and Map
                                  interfaces. Was this ever considered,
                                  and if <br>
                                  >> not, could it be?<br>
                                  > <br>
                                  > Thanks for re-starting that
                                  discussion, it was talked a bit, but
                                  not as <br>
                                  > it should be.<br>
                                  > <br>
                                  > So the issue is that currently we
                                  do not have any compact, unmodifiable
                                  <br>
                                  > and ordered Set/Map
                                  implementation,<br>
                                  > one use case is when you have
                                  data that comes from a JSON object as
                                  a <br>
                                  > Map and you want to keep the
                                  inserted order, if by example the JSON
                                  is <br>
                                  > a config file editable by a
                                  human, an other example is in unit
                                  tests <br>
                                  > where you want to help the dev to
                                  read the output of the test so the <br>
                                  > code that creates a Set/Map and
                                  what is outputed by the test should be
                                  <br>
                                  > in the same order.<br>
                                  > Currently there is no good
                                  solution for those use cases because <br>
                                  > Set|Map.copyOf() does not keep
                                  the ordering.<br>
                                  > <br>
                                  > I see two solutions, either we
                                  add a new <br>
                                  >
                                  SequenceSet|SequenceMap.of/copyOf, or
                                  we change the impleemntation of <br>
                                  > Set|Map.of()/copyOf().<br>
                                  > Python had gone for the latter
                                  solution, which has the advantage a <br>
                                  > being simple from the user POV,
                                  but from an algorithm expert POV, a
                                  Set <br>
                                  > and a SequencedSet are different
                                  concepts we may want to emphasis ?<br>
                                  > <br>
                                  >> Best regards, Rafael<br>
                                  > <br>
                                  > regards,<br>
                                  > Rémi<br>
                                </blockquote>
                              </div>
                            </blockquote>
                          </div>
                        </blockquote>
                      </div>
                    </blockquote>
                  </div>
                </blockquote>
              </div>
            </blockquote>
          </div>
        </blockquote>
      </div>
    </blockquote>
  </body>
</html>