I apologize for not reading the previous discussion about "Superclasses
of inline classes" (as of 19th of dec. 2019). I now see the intent was
to not use a special class modifier to express the feature of light
abstract class.
The intent was also to allow extending "light" abstract classes with
inline as well as non-inline classes. In that case, a modifier like
"inline" would be a strange way to express such thing.
Regards, Peter
On 8/26/20 11:01 PM, Peter Levart wrote:
Hi,
Perhaps I missed some previous discussion about this, but I can't
quite understand why a decision whether an abstract class is "light"
or "heavy" and consequently doesn't implement IdentityObject or does
implement, has to be implicit. Couldn't it be explicit like it is for
concrete classes? Couldn't the language allow saying:
public abstract inline class SuperInline {
// no instance fields allowed, no constructors allowed
}
vs.:
public abstract class SuperIdentity {
// everything allowed (but nothing required), implicitly
implements IdentityObject
}
A concrete or abstract inline class could only extend abstract inline
class.
A concrete or abstract non-inline class could only extend concrete or
abstract non-inline class.
With such explicitness about the intent (inline vs. non-inline) there
would be less unintentional surprises.
What do you think?
Regards, Peter
On 8/18/20 1:44 AM, Dan Smith wrote:
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.