On 1/17/2025 5:00 PM, David Alayachew wrote:

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.

Now that said, I don't understand your comment Joe Darcy. Could you explain it in more detail?

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

    "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"

(The generic information is basically erased in the class file, hence Set rather than Set<E> and Object rather than E.)

If we were then in JDK 25 to replace in java.util.Set

    static <E> Set<E> of(E e1){...}

with

    static <E> SequencedSet<E> of(E e1){...}

when your class file ran against JDK 25, there would be no method

    "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"

for your class to call and the linkage would fail.

For static methods, the change is equivalent to removing a method and adding back a different, same-named method.

HTH,

-Joe


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.

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.


On Fri, Jan 17, 2025, 12:32 PM Joseph D. Darcy <joe.da...@oracle.com> wrote:

    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