Records -- current status

Brian Goetz brian.goetz at
Fri Mar 16 21:28:37 UTC 2018

>      - Extension.  The proposal outlines a notion of abstract record,
>     which provides a "width subtyped" hierarchy.  Some have questioned
>     whether this carries its weight, especially given how Scala
>     doesn't support case-to-case extension (some see this as a bug,
>     others as an existence proof.)  Records can implement interfaces.
> I also suggest we avoid abstract records. A reference to one may seem 
> like a proper record but it will behave badly with regard to equals(). 
> I don't see the upside compared to a common interface, and then you 
> don't have to have the novel parameterized extends clause.

The hackneyed example: consider the below as a subset of a typical 
"model an expression with a tree" hierarchy.  Of course, a real 
hierarchy would have a lot more classes.

     sealed interface Node;
     record ValNode(int value) extends Node;
     record VarNode(String name) extends Node;
     abstract record BinOpNode(Node left, Node right) extends Node;
     record PlusNode(Node left, Node right) extends BinOpNode(left, right);
     record MulNode(Node left, Node right) extends BinOpNode(left, right);

Obviously there might be some common behavior for binary operation nodes 
that can be factored up into BinOpNode.  But also, there are times when 
matching against the abstract type makes sense too.  For example, if you 
want to traverse the tree and perform structural operations (say, detect 
if a tree contains a reference to the variable "x"), matching on 
abstract records is pretty useful:

     boolean containsVar(Node node, String name) {
         return switch (node) {
             case VarNode(String s) -> s.equals(name);
             case BinOpNode(var left, var right) -> containsVar(left, 
name) || containsVar(right, name);
             default -> false;

A client who is only interested in structural properties can match once 
on the abstract type, instead of matching explicitly on N effectively 
identical cases (and add more every time the hierarchy changes.)

> On the other hand. As much as I want everyone to stick to immutable 
> records as much as possible, it seems very costly to me to have to 
> introduce a new keyword for "not final", and have users keep track of 
> which things have which defaults. Let this just be "best practice", 
> like it already is for regular fields (make them final unless you have 
> good reason not to).

Pretend we already had non-final.  Does that change your inclination?  
(When we do sealed types, we're likely going to need a way to say 
non-sealed anyway.)

>      - Accessors.  Perhaps the most controversial aspect is that
>     records are inherently transparent to read; if something wants to
>     truly encapsulate state, it's not a record. Records will
>     eventually have pattern deconstructors, which will expose their
>     state, so we should go out of the gate with the equivalent.  The
>     obvious choice is to expose read accessors automatically.  (These
>     will not be named getXxx; we are not burning the ill-advised
>     Javabean naming conventions into the language, no matter how much
>     people think it already is.)  The obvious naming choice for these
>     accessors is fieldName().  No provision for write accessors;
>     that's bring-your-own.
> Method and field named identically is a slight concern. If we gain 
> field references using the same syntax as method references there 
> would probably be no way to refer to such a field. I'm pretty sure 
> this is not worth worrying about though.

I have a story for disambiguating field references...

>     Records could be safely made cloneable() with automatic support
>     too (like arrays), but not clear if this is worth it (its darn
>     useful for arrays, though.)
> People just really need to not use arrays anymore, and especially not 
> with records. imho we should have added immutable List and 
> ImmutableIntArray etc. classes a very long time ago. I know we won't 
> now due to our value type aspirations. In the meantime we're in a 
> weird place. Arrays are completely terrible except as 
> micro-optimizations to be used with great care.

OK, but do  you have an opinion on whether records should automatically 
acquire a clone() implementation?

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list