EG meeting, 2021-11-17

Brian Goetz brian.goetz at oracle.com
Mon Nov 22 15:22:11 UTC 2021


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

This is the second turn of the crank (the first was "you can extend 
Object only"), but as this conversation hinted, there may be a further 
turn where abstract identity-agnostic classes can contribute to the 
layout and initialization of a concrete final by-value class without 
pulling it into the world of new-dup-init.  The following is an 
exploration, not a proposal, but might help find the next turn of the 
crank.  The exposition is translational-centric but that's not essential.

An abstract class can contribute fields, initialization of those fields, 
and behavior.  We can transform:

     abstract class C extends ValueObject {  // no identity children, please
         T t;

         C(T t) { ... t = e ... }
     }

into

     interface C {
         abstract <V extends C> protected V withT(V v, T t);
         abstract protected T t();

         static<V extends C>  protected V init(V v, T t) {
            ... v = withT(v, e) ...
           return v;
        }
     }

and a subclass

     b2-class V extends C {
         U u;

         V(T t, U u) { super(t); u = e; }
     }

into

     b2-class V implements C {
         T t;   // pull down fields from super
         U u;

         V(T t, U u) {
             V this = initialvalue;
             this = C.init(this, t);
             this = this withfield[u] u;
         }
     }

The point of this exercise is to observe that the two components of C 
that are doing double-duty as both API points for clients of C and 
extension points for subclasses of C -- the constructor and the layout 
-- can be given new implementations for the by-value world, that is 
consistent with the inheritance semantics the user expects.

Again, not making a proposal here, as much as probing at the bounds of a 
new object model.

(I think this is similar to what you sketched in your next mail.)

> 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.goetz at 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 <kevinb at google.com> 
>>> wrote:
>>>
>>> 
>>> On Wed, Nov 17, 2021 at 7:05 PM Dan Heidinga <heidinga at 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. |kevinb at google.com
>


More information about the valhalla-spec-observers mailing list