On 1/16/2025 11:26 PM, Rafael Winterhalter wrote:
Would it even be possible to change the return types of Set.of(...) and Map.of(...) without breaking binary compatibility?


In short, no.

The methods in question are *static* methods. Switching to covariant overrides with more precise return types works for subclasses because of bridge methods.

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.

-Joe



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.

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.

Best regards, Rafael

Am Fr., 17. Jan. 2025 um 00:36 Uhr schrieb David Alayachew <davidalayac...@gmail.com>:

    I should also add, the documentation went out of their way to
    specify that iteration order is unspecified.

    Also, I see Rémi's comment, but that's even more unconvincing to me.

    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.

    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.

    When I get back, I can check myself.


    On Thu, Jan 16, 2025, 6:25 PM David Alayachew
    <davidalayac...@gmail.com> wrote:

        I guess let me ask the obvious question.

        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.

        Is there any way we can look this up in the bug database or
        something?


        On Thu, Jan 16, 2025, 2:28 PM Jens Lideström
        <j...@lidestrom.se> wrote:

            Having the result Map.of and Set.of preserve the insertion
            order would
            often be convenient.

            More often than not programs iterate over the contents of
            a maps and
            sets at some point. For example to present the values in a
            GUI, for
            serialisation, or even for error printouts. In all those
            cases having a
            fixed iteration order is much better than having a random
            iteration
            order.

            Often it is even a subtle bug to have a random iteration
            order. For
            example, I ran in to a situation where jdeps printed a
            error message
            containing a list of modules. But the list was in a
            different order on
            each run of the program! It took me a while to figure out
            that it was
            actually the same list. A possible explanation is that
            jdeps is
            implemented using Map.of or Set.of.

            Because of this I think I would be better if the most
            commonly used
            standard collection factories produced collections with a
            fixed
            iteration order.

            Guavas ImmutableMap and ImmutableSet also preserve
            insertion order.

            Regards,
            Jens Lideström


            On 2025-01-16 08:44, Remi Forax wrote:

            > -------------------------
            >
            >> From: "Rafael Winterhalter" <rafael....@gmail.com>
            >> To: "core-libs-dev" <core-libs-...@openjdk.java.net>
            >> Sent: Thursday, January 16, 2025 8:13:17 AM
            >> Subject: Factory methods for SequencedSet and SequencedMap
            >
            >> Hello,
            >
            > Hello,
            >
            >> I am happily taking SequencedSet and SequencedMap into
            use, but one
            >> inconvenience I encounter is the lack of factory
            methods for the two.
            >> In code where many (initial) collections have zero or
            one element (for
            >> later aggregation), I now write Set.of()/Set.of(one) and
            >> Map.of()/Map.of(key, value), as it makes the code
            shorter and more
            >> readable. Those collections are of course implicitly
            sequenced, but
            >> now I must make the variable type of the surrounding
            monad Set and
            >> Map, and simply assume that a LinkedHashSet or
            LinkedHashMap is used
            >> when a collection of more than one element is set,
            without requiring
            >> the interface type. This does not require any type
            casting, as I rely
            >> on the iteration order only, but the code loses some of
            its
            >> expressiveness.
            >> I did not find any discussion around introducing
            factories for
            >> SequencedSet.of(...) and SequencedMap.of(...), similar
            to those that
            >> exist in the Set and Map interfaces. Was this ever
            considered, and if
            >> not, could it be?
            >
            > Thanks for re-starting that discussion, it was talked a
            bit, but not as
            > it should be.
            >
            > So the issue is that currently we do not have any
            compact, unmodifiable
            > and ordered Set/Map implementation,
            > one use case is when you have data that comes from a
            JSON object as a
            > Map and you want to keep the inserted order, if by
            example the JSON is
            > a config file editable by a human, an other example is
            in unit tests
            > where you want to help the dev to read the output of the
            test so the
            > code that creates a Set/Map and what is outputed by the
            test should be
            > in the same order.
            > Currently there is no good solution for those use cases
            because
            > Set|Map.copyOf() does not keep the ordering.
            >
            > I see two solutions, either we add a new
            > SequenceSet|SequenceMap.of/copyOf, or we change the
            impleemntation of
            > Set|Map.of()/copyOf().
            > Python had gone for the latter solution, which has the
            advantage a
            > being simple from the user POV, but from an algorithm
            expert POV, a Set
            > and a SequencedSet are different concepts we may want to
            emphasis ?
            >
            >> Best regards, Rafael
            >
            > regards,
            > Rémi

Reply via email to