Allowing inheritance with Records?

forax at univ-mlv.fr forax at univ-mlv.fr
Fri Jan 5 12:40:21 UTC 2024


> From: "Vikram Bakshi" <vab2048 at gmail.com>
> To: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-dev" <amber-dev at openjdk.java.net>
> Sent: Friday, January 5, 2024 12:13:17 PM
> Subject: Re: Allowing inheritance with Records?

> > I almost spill my tea :)

> :)

>> Inheritance is about sharing behaviors, so the data behaviors should not change
>> too much. But business requirement, business data/computation changes are
> > frequent, so using inheritance is a kind of an an anti-pattern for data.

> Is it really an anti-pattern in all situations though? There have been times
> where I have wanted my record to inherit from a record representing some "id"
> which itself contains methods/behaviour. I can think of it being useful in some
> situations.

I will never pretend that I know all situations :) 

Also with an interface + default methods, you also get most the features of inheritance without using inheritance 

interface Identified { 
int id(); // abstract 

default void behavior() { 
System.our.println(id()); 
} 
} 

record Foo(int id) implements Identified { } 
record Bar(int id) implements Identified { } 

And as I said it can also written like this 

interface Identified { } // empty interface 
record Foo(int id) implements Identified { } 
record Bar(int id) implements Identified { } 

void behavior(Identified identified) { 
System.out.println(switch(identified) { 
case Foo(var id) -> id; 
case Bar(var id) -> id; 
}); 
} 

>> It's far far easier to use records, empty interfaces and pattern matching
>> (switch on types) when you want to define data and their business rules than
> > tryig to use inheritance for a case it will not work well.

> I think allowing the developer the flexibility to choose whether or not they
> would like inheritance would still be a valid "Java" way of doing things.

> I understand from Brian's email that record inheritance is currently shelved so
> we will have to wait and see if it ever becomes a priority (other upcoming
> features like the "state monad" for records are probably more important anyway
> [
> https://github.com/openjdk/amber-docs/blob/master/eg-drafts/reconstruction-records-and-classes.md
> |
> https://github.com/openjdk/amber-docs/blob/master/eg-drafts/reconstruction-records-and-classes.md
> ] ).

There is a technical reson to not allow inheritance of record. 
Components of records are trusted by the JIT, i.e. if the JIT see the value of a record component, instead of reading the value again from the instance, it can use the value directly 
(the values captured by a lambda works the same way BTW). 

Now enter inheritance, the constructor of the base class is called before the fields are initialized, so if a component is observed by the VM at that point, the default value (null, 0, false, etc) will be seen because the component is not yet initialized. And then the JIT may replace an access to the component by the default value instead of the proper value. 

As part of Valhalla, we are working to force the constructor of the base class to be called *after* the field values are initialized. 

> Regards,
> Vikram

regards, 
Rémi 

> On Fri, Dec 29, 2023 at 2:05 PM Remi Forax < [ mailto:forax at univ-mlv.fr |
> forax at univ-mlv.fr ] > wrote:

>>> From: "Vikram Bakshi" < [ mailto:vab2048 at gmail.com | vab2048 at gmail.com ] >
>>> To: [ mailto:amber-dev at openjdk.java.net | amber-dev at openjdk.java.net ]
>>> Sent: Thursday, December 28, 2023 3:59:10 PM
>>> Subject: Allowing inheritance with Records?

>>> Hello,

>>> Is the decision to not allow inheritance for records set in stone? Or will this
>>> be opened up and explored in the future?

>>> One of the goals of records (from Brian Goetz Devoxx talk) is to "model data as
>>> data", and allowing inheritance would offer a powerful way of modelling data.

>> I almost spill my tea :)
>> Inheritance is about sharing behaviors, so the data behaviors should not change
>> too much. But business requirement, business data/computation changes are
>> frequent, so using inheritance is a kind of an an anti-pattern for data.

>> It's far far easier to use records, empty interfaces and pattern matching
>> (switch on types) when you want to define data and their business rules than
>> tryig to use inheritance for a case it will not work well.

>>> Right now we have to write interfaces for fields which are shared/static methods
>>> for shared behaviour/copying and pasting - which I do not think is ideal.

>>> Regards,
>>> Vikram

>> regards,
>> Rémi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/amber-dev/attachments/20240105/d5b8a160/attachment-0001.htm>


More information about the amber-dev mailing list