on implementing state components as a first class concept

Joe Darcy joe.darcy at oracle.com
Fri Apr 26 18:04:46 UTC 2019


Hello,

On 4/25/2019 1:26 PM, Brian Goetz wrote:
> To be clear, you are not suggested having two _fields_ in the class file, right?  You are only talking about the JLM view of the world?
>
> For class file translation, fields, constructors, and methods are derived members, so we want to preserve everything about the declaration of the records somewhere, most likely an attribute that captures component names, signatures, annos, etc.
>
> So what you are suggesting is that in the JLM view, a record is seen as having two kinds of “class variables”, one set of fields and one set of “state components.”
>
> That we would end up distorting the translation of the fields to use a different name (even though this is an implementation detail) to avoid JLM issues suggests “tail wagging dog” to me.
>
> If the goal is that JLM clients should see record components as such, then perhaps we should expose records as a different kind of top level entity?

Records are a new kind of type and state components are a new kind of 
entity to model. There are some precedents in the javax.lang.model API 
for how these could be handled. Those precedents guided the initial 
javax.lang.model API design previously described on the list [1]. 
Quoting one point from that discussion:

"To avoid introducing a new top-level element category interface (like
variable, type, package, module), state components are regarded as a new
kind of VariableElement, a name-type pair with other ancillary
information possibly available too." [1]

Unpacking this design choice a bit, it would certainly be technically 
possible in javax.lang.model to have a new StateComponentElement 
interface (and visitor method, etc.) that would be be sort of element 
whose kind was STATE_COMPONENT. This scale of JLM update was done for 
modules. Modules were a much larger language change of course and that 
scope of change seemed unnecessary as a first-cut at records and their 
state components.

If the primary way to think of records is "records are special kinds of 
classes built around their state components" then the state components 
should be prominent in the model of record. This led to the 
getStateComponents method and STATE_COMPONENT ElementKind. The closest 
analogue to this situation is enum constants to an enum ("enum types are 
special kinds of classes built around their enum constants"). The 
TypeElement interface does *not* have a "getEnumConstants" method. 
Instead, the constants can be found by iterating over the enclosed 
elements and checking for a kind of ENUM_CONSTANT.

For an enum type, the compiler mostly "just" adds two mandated methods, 
valueOf​(String name) and values(), and the constants are a pretty 
direct mapping to public static final fields, as discussed in the manual 
way to code the pattern before the language feature. (There is more work 
in serialization and uses of enums in switch statements, etc.) For 
records, by default the compiler makes more entities per component:

* parameter of a constructor
* same-named accessor method
* private field
* usage in equals/hashCode/toString methods

so I thought a more prominent existence for "state component" as opposed 
to "just a private field" was called for. It would also be possible to 
do more or less what the implementation does now where the fields are 
marked with a kind of STATE_COMPONENT rather than FIELD. The conceptual 
question is then are the state components just fields with special 
handling or are they something that gets turned into fields (and methods 
and parameters...)? If they are just fields, the STATE_COMPONENT kind is 
still needed and the method on TypeElement could be dropped. Especially 
when reading a record from a class file, I think some indication will be 
needed state component versus normal instance field since I would 
suspect compilers (and potentially programmers at some point) will find 
a need for instance fields beyond just the state components.

HTH,

-Joe



More information about the amber-dev mailing list