E07237: a record exists only to carry data, but this concrete record has no fields (counting inherited ones) - give it a field, make it a class or component if it carries behaviour, or mark it 'as abstract' if it is the root of a record hierarchy

Category: E07xxx Full resolution · Reported in phase: FULL_RESOLUTION · Classification: RECORD_WITHOUT_FIELDS · All error codes

What went wrong

You have declared a RECORD that has no fields - none of its own and none inherited from a super record - and it is not abstract. A record exists only to carry data, so a concrete record with nothing to carry is pointless.

Worked examples

Compilable examples demonstrating this error and the correct fix:

  • ek9 -q 2237 (Can an EK9 record have no fields?)
  • ek9 -q 97 (What is the difference between classes and records in EK9?)

Rationale

RECORDS are for pure DATA; CLASSES and COMPONENTS are for BEHAVIOUR. A record cannot have methods (E07290), so a record with no fields holds nothing and does nothing. Every concrete record has at least one field, which is also why every concrete record defines what 'set' means (E07235).

How to fix it

Pick the one that matches what the type is for:

  1. It carries data: give it the field(s) it carries (good.ek9 below: a 'Reading' with a 'celsius' field).
  2. It carries behaviour (methods, no data): make it a 'class' or 'component'. A class or component with no fields is set simply by being present.
  3. It is the root of a record hierarchy: mark it 'as abstract'.

Common causes

  • Using a record as a quick marker type - use a class, or an enumeration
  • Forgetting to declare the fields after the record name
  • A polymorphic root record that was meant to be 'as abstract'

See also

  • E07237: concrete record with no fields (this error)
  • E07235: a type with fields must define 'operator ?'
  • E07290: records support only constructors and operators

Examples

Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.

Fails with E07237: a record exists only to carry data, but this concrete record has no fields (counting inherited ones) - give it a field, make it a class or component if it carries behaviour, or mark it 'as abstract' if it is the root of a record hierarchy

#!ek9
defines module error.e07237.bad

  defines record

    //A plain concrete record with nothing in it.
    Nothing

    //Operators alone do not make it carry anything.
    OnlyOperators
      operator $ as pure
        <- rtn as String: "only operators"

    //Open is not abstract: an open record with no fields can still be created, holding nothing.
    OpenButEmpty as open
      default operator ?

    //A field-less abstract root is legal...
    Shape as abstract
      default operator ?

    //...but a concrete sub-record of it must add the fields.
    EmptyShape extends Shape

    //Two levels down, still nothing anywhere in the hierarchy.
    AbstractMiddle extends Shape as abstract
      default operator ?

    EmptyLeaf extends AbstractMiddle

Fixed: Give it the data it carries

#!ek9
defines module error.e07237.good

  defines record

    Reading
      celsius <- 21.5
      default operator

Fixed: Make a field-less root abstract

#!ek9
defines module error.e07237.good.root

  defines record

    //A field-less abstract root
    Measurement as abstract
      default operator ?

    Length extends Measurement as open
      metres <- 3.0
      default operator ?

    //Adds no fields, but inherits metres
    Height extends Length

Questions and answers

These Q&A entries show E07237 and its fix: