Can an EK9 record have no fields?
← Classes and OOP · Ref: Q2237
Only if it is abstract. A record exists only to carry data - it cannot have methods (E07290) - so a CONCRETE record with no fields, counting the ones it inherits, would hold nothing and do nothing: that is E07237. Two field-less shapes stay legal. An ABSTRACT record may have no fields: it is the root of a record hierarchy, the polymorphic type its sub-records share (Measurement below). And a sub-record may add no fields of its own when it INHERITS some (Altitude below inherits 'metres' from Length). For anything else, give the record the field it carries; if it was meant to carry behaviour, make it a class or component (a class or component with no fields is set simply by being present); if it was meant as a marker of one of a fixed set of values, use an enumeration. Every concrete record therefore has a field, which is also why every concrete record defines what 'set' means with its own '?' (E07235).
Example
defines module qa.records.need.fields defines record //A concrete record: it carries one field. Reading celsius <- 21.5 default operator //The root of a record hierarchy may have no fields: it is abstract. Measurement as abstract operator $ as pure abstract <- rtn as String? default operator ? Length extends Measurement as open metres as Float: Float() Length() as pure -> distance as Float metres :=? distance default operator $ default operator ? //Adds no field of its own, but inherits 'metres'. Altitude extends Length Altitude() as pure -> height as Float super(height) default operator $ defines function describe() -> measurement as Measurement <- rtn as String: $measurement defines program RecordsNeedFields() stdout <- Stdout() reading <- Reading() stdout.println($reading) stdout.println(describe(Length(3.0))) stdout.println(describe(Altitude(8848.0)))
Common mistakes
E07237 — With its only field removed, the concrete record 'Reading' carries no data, and a record cannot have methods either, so it is pointless. 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. See ek9 -h E07237 for details.
Incorrect:
Reading
Correct:
Reading
celsius <- 21.5
Other ways to ask this
- Why does EK9 reject an empty record?
- Can I use an empty record as a marker type in EK9?
- What does E07237 mean for a record?
- Can an abstract record have no fields in EK9?
Coming from another language?
Java: an empty record 'record Marker() {}' compiles, and is used as a marker or tag. Kotlin: a data class needs at least one primary constructor parameter - the same rule as EK9, without EK9's abstract-root exception (Kotlin uses a sealed interface for that). Python: an empty @dataclass is legal. EK9 follows Kotlin: a record is data, so a concrete one must carry some; a polymorphic root is an abstract record (or a trait).
Keywords: abstract record, marker type, record, data class, empty record, record hierarchy, no fields, field-less