Yes. One way I like to think about the Old Bucket is that it is characterized by *concrete* representations which have somehow opted into object identity.
Confusingly, the Old Bucket also contains interfaces which are non-concrete and also Object, which might as well be non-concrete. (I’m not saying “abstract” because that’s a keyword in the language, and you can have semi-concrete classes which are abstract but also commit to object identity and may even have mutable fields or by-reference constructors, like AbstractList.) Those are the two interesting populations in the Old Bucket: Concrete classes that are entangled with object identity (until they can be migrated, or forever in many cases). And, non-concrete classes, which are necessarily polymorphic. Those two kinds of types (in the Old Bucket) interact with the New Buckets in distinct ways. There’s a middle case which is causing problems here: A class can be concrete *and* polymorphic, meaning that subclasses can add more stuff. (The parent class could be declared abstract or not; that’s not an important detail.) A class that is concrete *and* polymorphic is exactly one that plays the classic game of object oriented subclasses, where data fields and methods are refined in layers. This classic game does not translate well into the by-value world; it needs polymorphic pointers. Just consult any C++ style guide to see what happens if you unwarily try to mix by-value structs and class inheritance: You shouldn’t, according to the guides. Is there a way to make that work in Java, so that identity-free classes can inherit from each other? Probably, in some limited way. The simplest move is the one Brian and I are liking here, where a completely non-concrete class (one with no fields and no commitment to object identity) can be refined by a subclass. But it should be marked abstract, so as not to have cases where you have a variable of the super-type and you don’t know whether it has the layout of the super (because it was concrete, oops) or a subtype. The division separating non-concrete types from identity-object types in the Old Bucket may be seen in this diagram, which I cobbled up this weekend: http://cr.openjdk.java.net/~jrose/values/type-kinds-venn.pdf This comes from my attempts to make a more or less comprehensive Venn-style diagram of the stuff we are talking about. I think it helps me better visualize what we are trying to do; maybe it will help others in some way. I view this as my due diligence mapping the side of the elephant I can make contact with. Therefore I’m happy to take corrections on it. I’m also noodling on a whimsical Field Guide, which asks you binary questions about a random Java type, and guides you towards classifying it. That helped me crystallize the diagram, and may be useful in its own right, or perhaps distilled into a flowchart. Stay tuned. — John On Nov 18, 2021, at 2:34 PM, Brian Goetz <brian.go...@oracle.com<mailto:brian.go...@oracle.com>> wrote: I think it is reasonable to consider allowing bucket two classes to be abstract. They could be extended by other classes which would either be abstract or final. The intermediate types are polymorphic but the terminal type is monomorphic. A similar argument works for records. Sent from my iPad On Nov 18, 2021, at 5:27 PM, Kevin Bourrillion <kev...@google.com<mailto:kev...@google.com>> wrote: On Wed, Nov 17, 2021 at 7:05 PM Dan Heidinga <heidi...@redhat.com<mailto:heidi...@redhat.com>> wrote: Let me turn the question around: What do we gain by allowing subclassing of B2 classes? I'm not claiming it's much. I'm just coming into this from a different direction. In my experience most immutable (or stateless) classes have no real interest in exposing identity, but just get defaulted into it. Any dependency on the distinction between one instance and another that equals() it would be a probable bug. When B2 exists I see myself advocating that a developer's first instinct should be to make new classes in B2 except when they need something from B1 like mutability (and perhaps subclassability belongs in this list too!). As far as I can tell, this makes sense whether there are even any performance benefits at all, and the performance benefits just make it a lot more motivating to do what is already probably technically best anyway. Now, if subclassability legitimately belongs in that list of B1-forcing-factors, that'll be fine, I just hadn't fully thought it through and was implicitly treating it like an open question, which probably made my initial question in this subthread confusing. -- Kevin Bourrillion | Java Librarian | Google, Inc. | kev...@google.com<mailto:kev...@google.com>