What do I get for free with an EK9 enumeration?

← Enumerations · Ref: Q219

From a bare list of values you get 28 auto-generated members: 24 operators, 3 constructors, and an iterator. No annotations, no derive macros, no boilerplate.

COMPARISON OPERATORS (7 enum-vs-enum)
Every enumeration gets ==, <>, <, >, <=, >=, and <=> for full ordering based on declaration order. No Comparable interface to implement.

STRING COMPARISON OPERATORS (7 enum-vs-String)
The same seven comparison operators work with String arguments directly: season == "Spring" works without any conversion.

CONVERSION OPERATORS

$ converts to String, #^ promotes to String, $$ converts to JSON, and #? returns a hashcode Integer.

QUERY OPERATORS

? checks if the enum is set. #< returns the first declared member. #> returns the last declared member.

MUTATING OPERATORS

++ advances to the next member. -- goes to the previous member. Both go to unset at boundaries.

CONSTRUCTORS (3)

Colour() creates unset. Colour("Red") creates from string (unset if invalid). Colour(existing) copies.

ITERATOR

'for colour in Colour' iterates all members. 'cat Colour' streams them.

See Q99 for basic enumeration syntax. See Q220 for navigation with increment and decrement. See Q221 for string comparison details. See Q96 for class operators.

Example

defines module qa.enums.batteries

  defines type

    Colour
      Red
      Green
      Blue

  defines program

    EnumBatteriesDemo()
      stdout <- Stdout()

      red <- Colour.Red
      blue <- Colour.Blue

      // === COMPARISON OPERATORS (enum vs enum) ===

      stdout.println(`Equal: ${red == Colour.Red}`)
      stdout.println(`Not equal: ${red <> blue}`)
      stdout.println(`Less than: ${red < blue}`)
      stdout.println(`Greater than: ${blue > red}`)
      stdout.println(`Less or equal: ${red <= Colour.Red}`)
      stdout.println(`Greater or equal: ${blue >= red}`)
      stdout.println(`Compare: ${red <=> blue}`)

      // === STRING COMPARISON OPERATORS ===

      stdout.println(`Eq string: ${red == "Red"}`)
      stdout.println(`Neq string: ${red <> "Blue"}`)
      stdout.println(`Lt string: ${red < "Green"}`)

      // === CONVERSION OPERATORS ===

      stdout.println(`String: ${red}`)
      stdout.println(`Promote: ${#^red}`)
      stdout.println(`JSON: ${$red}`)
      stdout.println(`Hashcode: ${#?red}`)

      // === QUERY OPERATORS ===

      stdout.println(`IsSet: ${red?}`)
      stdout.println(`First: ${#< red}`)
      stdout.println(`Last: ${#> red}`)

      // === CONSTRUCTORS ===

      fromString <- Colour("Green")
      stdout.println(`From string: ${fromString}`)

      invalid <- Colour("Purple")
      stdout.println(`Invalid isSet: ${invalid?}`)

      unsetColour <- Colour()
      stdout.println(`Unset isSet: ${unsetColour?}`)

      copied <- Colour(red)
      stdout.println(`Copied: ${copied}`)

      // === ITERATION ===

      for colour in Colour
        stdout.println(`Iterate: ${colour}`)

      colours <- cat Colour | collect as List of Colour
      stdout.println(`Collected: ${length colours}`)

Common mistakes

E50060 — EK9 enumerations have no toString() method — use the $ operator (or plain ${...} interpolation) for String conversion. See ek9 -h E50060 for details.

Incorrect:

      stdout.println(`String: ${red.toString()}`)

Correct:

      stdout.println(`String: ${red}`)
Other ways to ask this
  • What operators does an EK9 enum automatically have?
  • How many members does an EK9 enumeration generate?
  • What comes built-in with EK9 enumerations?

Coming from another language?

Java: toString(), valueOf(), compareTo(), equals() generated but no first/last, no increment/decrement, no string-parameter comparison, no JSON, no safe string construction. Python: needs @total_ordering for ordering, no iteration operators, no JSON. Rust: needs #[derive(PartialOrd, Ord, PartialEq, Eq)] plus strum crate for iteration and string conversion. Go: hand-written everything, iota gives integers only. Kotlin: entries property but no ordering operators, no increment/decrement, no JSON. Swift: CaseIterable for iteration, Comparable conformance needed for ordering, no increment/decrement, no string construction from String, associated values add power but also complexity. C#: limited to integer-based comparison, no string construction. EK9: 28 members from a bare value list, zero boilerplate.

Keywords: boilerplate, automatic, enumeration, operator, migrate, free, built-in, generated, swift, batteries, included