It definitely helps. 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?
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. On Fri, Jan 17, 2025, 8:14 PM Joseph D. Darcy <joe.da...@oracle.com> wrote: > > 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 >>>>> >>>>