Why can't I provide a signature or body when using 'default operator' in EK9?
← Classes and OOP · Ref: Q835
The 'default' keyword on an operator means 'compiler, auto-generate this operator from the existing fields and prerequisite operators'. Adding a signature, modifiers like 'as pure', parameters, or a body contradicts this — you are simultaneously asking the compiler to generate it AND manually specifying it.
THE RULE
- 'default operator <=>' — valid, compiler generates comparator
- 'default operator' — valid, compiler generates ALL supported operators
- 'default operator >= as pure' — ERROR E07230, contradictory
- 'default operator ? as pure <- rtn as Boolean: x?' — ERROR E07230, contradictory
WHY IT IS AN ERROR
If you want auto-generation, write 'default operator <name>' with nothing else. If you want a custom implementation, write the full operator without 'default'. Mixing the two indicates a misunderstanding of what 'default' means.
PREREQUISITE OPERATORS
Some default operators require other operators to exist first. For example, 'default operator >=' needs the comparator '<=>'. You can provide '<=>'' explicitly and default the rest.
THIS EXAMPLE
The Shape record provides an explicit comparator, then uses 'default operator' to auto-generate all remaining supported operators (>=, <=, >, <, ==, <>, $, #?).
See Q116 for default operator overview. See Q96 for operator semantics. See Q774 for abstract constructor.
Example
defines module qa.classesandoop.default.operator.signature defines record Shape name <- String() sides <- 0 Shape() -> n as String s as Integer name :=: n sides :=: s //Explicit comparator — prerequisite for defaulting >=, <=, etc. operator <=> as pure -> arg0 as Shape <- rtn as Integer: sides <=> arg0.sides //Auto-generate ALL remaining supported operators default operator defines class Config label <- "default" priority <- 0 default Config() Config() -> l as String p as Integer label :=: l priority :=: p describe() <- rtn as String: `${label} (priority ${priority})` //Explicit comparator operator <=> as pure -> arg0 as Config <- rtn as Integer: priority <=> arg0.priority //Selective default — just the isSet operator default operator ? defines program DefaultOperatorDemo() stdout <- Stdout() triangle <- Shape("triangle", 3) square <- Shape("square", 4) if triangle? stdout.println(`Triangle >= Square: ${triangle >= square}`) stdout.println(`Triangle == Square: ${triangle == square}`) stdout.println("Triangle $: " + $triangle) c1 <- Config("high", 10) c2 <- Config("low", 1) if c1? stdout.println(c1.describe()) stdout.println(`c1 > c2: ${c1 <=> c2 > 0}`)
Common mistakes
E07230 — Cannot provide a signature or body with 'default operator'. The keyword 'default' means the compiler generates it. Either remove 'default' and write the operator manually, or remove the signature/body. See ek9 -h E07230 for details.
Incorrect:
//Auto-generate ALL remaining supported operators default operator >= as pure -> arg0 as Shape <- rtn as Boolean: false
Correct:
//Auto-generate ALL remaining supported operators default operator
E07230 — Providing 'as pure' modifier and a body with 'default' is contradictory. Use 'default operator ?' alone for auto-generation, or remove 'default' and write the full operator. See ek9 -h E07230 for details.
Incorrect:
default operator ? as pure <- rtn as Boolean: name?
Correct:
default operator ?
Other ways to ask this
- What is E07230 DEFAULT_WITH_OPERATOR_SIGNATURE?
- Why does 'default operator >= as pure' fail to compile?
- What does 'default' mean on an operator and why can't I add parameters?
Coming from another language?
Java: no operator overloading or auto-generation. Kotlin: data class generates all-or-nothing. Rust: #[derive(PartialEq, Hash)] is selective auto-generation. EK9: 'default operator' is selective, but 'default' and manual specification are mutually exclusive — prevents contradictory declarations.
Keywords: auto-generate, contradictory, default, pure, operator, modifier, prerequisite, signature, E07230, body