[records] Record updates for Preview/2

Brian Goetz brian.goetz at oracle.com
Wed Jan 8 23:55:10 UTC 2020


We're gathering a list of what non-bugfix things we want to do for the 
second preview of records.  So far, on my list, I have:

1.  Revisiting the j.l.Record supertype.  We want to support inline 
records when we have inline types.  Until now, we've been working on the 
assumption in Valhalla that inline classes can only extend interfaces, 
not abstract classes, so it was suggested that Record should be an 
interface.  However, that topic in Valhalla is under reconsideration, 
and I want to wait until that discussion plays out before making any 
changes here.

It has also been pointed out that the name Record is somewhat clash-y.  
I'm not really willing to pick a lousy name just to reduce the chance of 
clashes, but I might be OK with a name like RecordClass.  (Bikeshed 
alert: if you want to discuss any of these topics, please start a new 
thread; this one is about curating a to-do list.)

2.  Accessibility of mandated members.  Remi noted that the requirement 
that the mandated record members be public, even for non-public classes, 
was weird.  But, at the time, the spec was in a state that trying to 
revisit this was impractical -- Gavin has now left the spec in a much 
cleaner place, and so it is reasonable to reopen this discussion.  The 
leading alternate candidate is to propagate the accessibility of the 
record to its mandated members (public for public, etc), but still 
require the author to say what they mean.

3.  Nesting considerations.  In 14 we will fix the issues surrounding 
local records, but we still ban nested records in non-static classes.  
We should fix this -- by dropping the restriction on static members in 
inner classes -- and then bring records, enums, and interfaces to parity 
(allowing local and nested flavors of all, all implicitly static.)

4.  Abstract records.  Several people have asked "what about abstract 
records"; while these are theoretically possible, there are some 
complications that I think are best left for treating these as a later 
addition if needed.  But, for the record, here are some thoughts from 
the last time I looked into this.

Given that records are nominal tuples, the notion of "width subtyping" 
comes immediately to mind.  So, let's go with that for a moment: you 
could say

     abstract record A(int a, int b) { }
and
     record B(int a, int b, int c) extends A { }

and there is a natural width subtyping relationship.  We don't have 
problems with the equality contract because the abstract class leaves 
equals() abstract.

But, this is a story that is likely to not be entirely satisfactory.  Do 
we require that the state of A form a prefix for the state of B?  This 
may not be the API people want.  Do we require that super(a,b) be passed 
through unchanged?  The constraints on the subclass in this model get, 
constraining.

What if there were a more flexible relationship:

     record B(int a, int b, int c) extends A(a, b) { }

Now, there's more flexibility, at the cost of a new "extends" 
construct.  And what if you want to fix some field of A as a constant:

     record iload2_bytecode() extends bytecode(0x1c) { }

These all seems like reasonable things to want when you get into 
abstract records ... but they all start to push on the "records 
imperative".  So for now, we're doing nothing, until we have a better 
story for what we actually want to do.

5.  Deconstruction patterns.  Yes, records should be deconstructible 
with deconstruction patterns.


Anything else, that we've already discussed that I left out?




-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/amber-spec-experts/attachments/20200108/9af214ef/attachment.htm>


More information about the amber-spec-experts mailing list