Skip to content
This repository was archived by the owner on Apr 25, 2025. It is now read-only.
This repository was archived by the owner on Apr 25, 2025. It is now read-only.

Field Accessors #238

Closed
Closed
@RossTate

Description

@RossTate

This is a suggestion for a different way to design the instructions for getting/setting fields, which for lack of a better term I'll refer to as "field accessors".

Design

After processing the types section of the module, we'll get two lists: the list of types, and the list of field accessors. When processing a (nominal) type in the types section, for every field of the type a corresponding field accessor is automatically added to the field-accessor list. The type of the field accessor depends on the qualities of the field, e.g. what is its value type, and is the field writable? The "receiver" type of the field accessor is whatever (nominal) type it was generated from.

So, if one defines a nominal type, say $Foo, with a mutable i32 field followed by an immutable i64 field, then there will also be two field accessors, say $x and $y, where the type of $x is "receiver type is $Foo, value type is i32, and mutability is mutable" and the type of $y is "receiver type is $Foo, value type is i64, and mutability is immutable". The text format could provider room for declaring the field-accessor names $x and $y, which get bound to their corresponding indices in the generated field-accessor list.

Then the instructions for getting and setting a field simply include a field-accessor index, rather than both a type and an index. The type of the corresponding field accessor determines the receiver type that must be on the stack and the value type that either is returned (for getting) or must be on the stack (for setting). For setting, the field accessor must also be mutable.

To clarify, this is not the same as the field members described in the Post-MVP. Field members in the Post-MVP are essentially the first-class variant on field accessors.

Motivation

Short-term reasons to use field accessors:

  • Primary: Reduces code size without introducing any type-checking complexity: the get/set instructions now have only one index rather than two.
  • The names section can give a name to each field accessor, which is helpful for debugging
  • I also wouldn't be surprised if it's more straightforward/efficient to compile and interpret.

Longer-term reasons to use field accessors:

  • Another way to reduce code size is to simply synthesize the receiver's type rather than explicitly specify its index in the get/set instruction, but that runs into type-checking complexity issues when combined with extensions like multiple upper-bounds (as described in Complications with multiple upper bounds #160), whereas field accessors retain efficient type-checking even in the presence of such extensions.
  • Field accessors make it easy for one to import just the fields of another module's types that it actually depends on, and similarly to give other modules access to just the public fields of one's own types without having to also give them access to private fields.

Accompanying Extension

Field accessors would also facilitate another extension or variation. When one defines a nominal type that extends another nominal type, we could avoid repeating the fields of the other nominal type and simply state the new fields of the new type. In the short term, this would reduce the size of the types section. In the long term, this would facilitate separate compilation of subclasses (particularly in the presence of private fields of the superclass).

Whether we actually want this accompanying extension should be discussed later and somewhere else; I just mention it here as another motivation for field accessors.

Transfer

Although I came up with this for nominal types, the idea likely transfers to structural types.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions