What are the rules for using 'default operator' in EK9?
← Operators and Expressions · Ref: Q949
default operator rules: in an extending class the SUPER must have the operator, and property types must support the required operators.
1. THE SUPER MUST HAVE THE OPERATOR (E07190)
A defaulted operator in an extending class calls the super's operator first, then the new fields. So a subclass may use 'default operator X' only if its super has operator X. If the super lacks it, compilation fails with E07190: add X to the super (written or defaulted), or write X by hand in the subclass. A parent and a subclass may both say 'default operator $'. The one case where the parent having it blocks the child is sameness (<=> or ==, and #?), which is declared once per hierarchy (E07182) - see rule 3. See Q1314.
2. PROPERTY TYPE REQUIREMENTS (E07200)
When you use 'default operator <=>', all property types in the class must support <=>. If any property's type lacks the operator, compilation fails with E07200.
3. SAMENESS IS REQUESTED ONCE
Request the sameness only: 'default operator <=>' (or 'default operator ==' for a type with a field that cannot be ordered, such as a List). ==, <>, <, <=, >, >= are then generated from it; also asking for 'default operator ==' or 'default operator <>' beside '<=>' is E07181.
DEFAULT OPERATOR BEHAVIOR
'default operator' generates field-by-field implementations:
default operator <=> compares all fields in declaration order (== and <> follow from it) default operator $ concatenates field string representations default operator ? checks all fields are set
See Q116 for default operator syntax. See Q245 for custom operators.
Example
defines module qa.operators.defaultrules defines class <?- Class using default operators. All property types (String, Integer) support <=>, $, ?. -?> Person name <- String() age <- Integer() default private Person() as pure Person() as pure -> name as String age as Integer this.name :=: name this.age :=: age //default generates field-by-field comparison; == and <> are generated from <=> default operator <=> default operator $ default operator #? default operator :=: override operator ? as pure <- rtn as Boolean: name? and age? defines program DefaultOperatorRulesDemo() stdout <- Stdout() p1 <- Person("Alice", 30) p2 <- Person("Alice", 30) p3 <- Person("Bob", 25) stdout.println(`p1 == p2: ${p1 == p2}`) stdout.println(`p1 == p3: ${p1 == p3}`) stdout.println(`p1: ${p1}`) stdout.println(`p1 set: ${p1?}`)
Common mistakes
E02030 — The class already has 'default operator <=>' defined. Changing $ to <=> creates a duplicate operator definition, triggering E02030. Each operator can only be defined once. See ek9 -h E02030 for details.
Incorrect:
default operator <=>
Correct:
default operator $
Other ways to ask this
- What triggers E07190 MISSING_OPERATOR_IN_SUPER?
- What triggers E07200 PROPERTY_TYPE_MISSING_OPERATOR?
- Can I use default operator in a class that extends another?
- Why do my properties need operators for default to work?
Coming from another language?
Java: IDE-generated equals/hashCode. Python: dataclass auto-generates. Rust: derive(Eq, Hash). Kotlin: data class auto-generates. EK9: 'default operator' with compile-time validation that property types support the required operator.
Keywords: operator, extending, default, field, property, type, auto, E07190, generate, E07200