> De: "John Rose" <john.r.r...@oracle.com> > À: "Remi Forax" <fo...@univ-mlv.fr> > Cc: "Peter Levart" <peter.lev...@gmail.com>, "Rémi Forax" > <fo...@openjdk.java.net>, "core-libs-dev" <core-libs-dev@openjdk.java.net> > Envoyé: Vendredi 4 Juin 2021 02:05:41 > Objet: Re: [External] : Re: RFR: 8199318: add idempotent copy operation for > Map.Entry
> On Jun 3, 2021, at 3:17 PM, [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] > wrote: >>> De: "John Rose" <john. [ mailto:r.r...@oracle.com | r.r...@oracle.com ] > >>> À: "Remi Forax" < [ mailto:fo...@univ-mlv.fr | fo...@univ-mlv.fr ] > >>> Cc: "Peter Levart" < [ mailto:peter.lev...@gmail.com | >>> peter.lev...@gmail.com ] >>> >, "Rémi Forax" < [ mailto:fo...@openjdk.java.net | fo...@openjdk.java.net >>> >] >, >>> "core-libs-dev" < [ mailto:core-libs-dev@openjdk.java.net | >>> core-libs-dev@openjdk.java.net ] > >>> Envoyé: Jeudi 3 Juin 2021 22:51:28 >>> Objet: Re: RFR: 8199318: add idempotent copy operation for Map.Entry >>> ... >>> interface ComparableRecord<T extends Record & ComparableRecord<T>> >>> extends Comparable<T> { … } >>> record Foo(int x, String y) implements ComparableRecord<Foo> { … } >>> [ http://cr.openjdk.java.net/~jrose/draft/ComparableRecord.java | >>> http://cr.openjdk.java.net/~jrose/draft/ComparableRecord.java ] >> [repost with a link] >> The main issue with this kind of code is that the JIT does not see through >> the >> ClassValue. > Wow, it’s almost as if we’ve discussed this already! ;-) > So, [ https://bugs.openjdk.java.net/browse/JDK-8238260 | > https://bugs.openjdk.java.net/browse/JDK-8238260 ] > Part of my agenda here is finding more reasons why > JDK-8238260 deserves some love. > Currently, the translation strategy for Records > requires a lot of boilerplate generated into each > subclass for toString, equals, and hashCode. > It is partially declarative, because it uses indy. > So, yay for that. But it is also a bad smell (IMO) > that the trick needs to be played in each subclass. > If ClassValue were performant, we could have > just one method in Record for each of toString, > equals, and hashCode, and have them DTRT. > The user code would then be able to call > super.toString() to get the standard behavior > in a refining wrapper method in a subclass. > Looking further, it would be nice to have methods > which (a) inherit from supers as reusable code > ought to, but (b) re-specialize themselves once > per subclass indy-style. This is a VM trick I hope > to look into after we do specialization. For now, > ClassValue is the way to simulate that. yes, it's a specialization problem. I wonder if it an be resolved using a combination of a species-static variable and magic shibboleth to ask the type parameter to be always reified interface ComparableRecord <please-always-reified-me T extends Record & ComparableRecord< T > > extends Comparable< T > { species-static Comparator<T> COMPARATOR; // a parameteric condy ? species-static { COMPARATOR = ... } default int compareTo(T other) { return COMPARATOR.compare(this, other); } } >> Tweaking a little bit your code, I get >> [ >> https://urldefense.com/v3/__https://gist.github.com/forax/e76367e1a90bf011692ee9bec65ff0f8__;!!GqivPVa7Brio!MheW9rHDHXlXYNKUju7v5G0vXlpj1YOoDWFjG9AcpnXnVz2TxlMYDM7i86yFtT_B$ >> | https://gist.github.com/forax/e76367e1a90bf011692ee9bec65ff0f8 ] >> (It's a PITA that we have to use a raw type to workaround circularly defined >> parameter type) > I tried to DTRT and got into Inference Hell, surrounded > by a swarms of unfriendly wildcards with pitchforks. > Glad it wasn’t just me. > Inspired by your more whole-hearted use of streams > to build the code, I updated my example. Thanks. > — John Rémi