There's an interesting interaction between IdentityObject and abstract 
superclasses of inline classes that might be worth leaning into.

---

The "status quo" (inasmuch as one exists):

An inline class can extend a class if it, and all of its supers, 1) are 
abstract, 2) declare no instance fields, and 3) have "empty" <init> methods. 
These properties represent a new kind of abstract class—call it a "light" 
abstract class. Changing a "light" abstract class to be "heavy" is a binary 
incompatible change.

Separately, we have the IdentityObject interface, which is implicitly attached 
to all non-inline concrete classes. An abstract class might also be able to 
implement IdentityObject explicitly, and doing so would also disqualify it from 
being an inline class super.

A struggle in this story is getting programmers to care about whether their 
classes are "heavy" or "light", since even though it's an important property, 
it's easy to overlook (there's no syntax for it, and in many cases, there are 
no immediate effects).

---

Alternative story:

An inline class must not extend IdentityObject through any of its superclasses. 
(That's it.)

A non-inline class implicitly implements IdentityObject if it 1) is concrete, 
2) declares an instance field, or 3) has a non-empty <init> method. Abstract 
classes can also explicitly implement IdentityObject.

Changing a class so that it implements IdentityObject is a binary incompatible 
change.

Now we have a highly-visible concept (IdentityObject) that programmers should 
generally be aware of anyway, and they should readily understand a difference 
between abstract classes that implement IdentityObject and those that don't.

---

I think I like the alternative story. It feels simpler.

One reason to avoid it is if we think there's potentially value in a "light" 
abstract class concept that is independent of IdentityObject. For example, 
maybe some other feature could build on the idea of a superclass that requires 
no initialization, without tying that to the topic of object identity. I'm 
having trouble envisioning a use case, though. Another reason to avoid it is if 
we want IdentityObject to be limited to concrete classes—no explicit 
implementing it allowed.

If the alternative story is the one we want, it implies that the "empty <init>" 
JVM feature should be part of Inline Classes, not a separate thing we deliver 
earlier—because it's directly tied to IdentityObject.

Reply via email to