How do I define an Event record with Date, Time, and String fields and compare two events?
← Operators and Expressions · Ref: Q1195
Define a record with typed fields, a constructor, and 'default operator' to get field-by-field comparison, equality, copy, isSet, and string conversion.
RECORD DEFINITION
Event
eventDate as Date: Date()
eventTime as Time: Time()
title as String: String()
constructor, then 'default operator' LAST
DEFAULT OPERATOR
'default operator' generates ==, <>, <, >, <=, >=, <=>, $, ?, :=:, #? and more from the fields. It must be the LAST thing in the record body.
COMPARISON
if eventA < eventB field-by-field comparison if eventA == eventB field-by-field equality
Records have public fields — no getters needed. Since every field (Date, Time, String) supports operators, the default operator works seamlessly across all of them.
See Q116 for default operator. See Q245 for custom type operators. See Q238 for the complete operator set.
Example
defines module qa.operators.mixedtypeclass defines record Event eventDate as Date: Date() eventTime as Time: Time() title as String: String() Event() as pure -> theDate as Date theTime as Time theTitle as String this.eventDate :=: theDate this.eventTime :=: theTime this.title :=: theTitle default operator defines program MixedTypeClassDemo() stdout <- Stdout() // === CREATE EVENTS === eventA <- Event(2024-03-15, 09:00, "Sprint Planning") eventB <- Event(2024-03-15, 14:00, "Retrospective") eventC <- Event(2024-06-01, 10:00, "Release Review") // === COMPARISON (field-by-field via default operator) === if eventA < eventB stdout.println("Sprint Planning is before Retrospective") require eventA < eventB require eventB < eventC require eventA <> eventB // === EQUALITY === sameAsA <- Event(2024-03-15, 09:00, "Sprint Planning") require eventA == sameAsA stdout.println(`Events equal: ${eventA == sameAsA}`) // === SPACESHIP ORDERING === ordering <- eventA <=> eventC stdout.println(`Planning <=> Release: ${ordering}`) require ordering < 0 // === STRING CONVERSION === eventStr <- $eventA stdout.println(`Event: ${eventStr}`) // === ISSET === require eventA? unsetEvent <- Event() require ~unsetEvent? // === COPY OPERATOR === copied <- Event() copied :=: eventA require copied == eventA stdout.println(`Copied event: ${copied}`) // === COALESCING === earlier <- eventA <? eventC later <- eventA >? eventC stdout.println(`Earlier event: ${earlier}`) stdout.println(`Later event: ${later}`) require earlier == eventA require later == eventC
Common mistakes
E06820 — The 'default operator' must be the LAST declaration in the record body. Placing fields or methods after it triggers E06820. See ek9 -h E06820 for details.
Incorrect:
default operator title as String: String() (fields after default operator)
Correct:
default operator defines program
Other ways to ask this
- Create a record with multiple built-in type fields and use default operators.
- I need to build an Event record with temporal fields and compare instances.
- In Java I implemented Comparable on a multi-field class — how does EK9 do this?
Coming from another language?
Java: implement Comparable, override equals/hashCode/toString manually. Python: @dataclass with order=True. Rust: #[derive(Eq, Ord)]. Kotlin: data class. Go: manual comparison functions. EK9: 'default operator' auto-generates all operators from fields, one line replaces boilerplate.
Keywords: record, default, operator, string, event, compare, fields, date, mixed, constructor, time