What built-in generic types does EK9 provide?

← Generics · Ref: Q198

EK9 provides several built-in generic types. These are closed by default and cannot be extended. Use composition (wrapping) instead of inheritance.

LIST OF T

Ordered collection:

  names <- List() of String
  names += "Alice"

DICT OF (K, V)

Key-value mapping:

  ages <- Dict() of (String, Integer)

OPTIONAL OF T

May or may not contain a value:

  maybe <- Optional("hello")

RESULT OF (OK, ERR)

Success or error value:

  result <- Result(42, String())

ITERATOR OF T

Lazy sequence of values from .iterator() on collections.

MUTEXLOCK OF T

Thread-safe wrapper for concurrent access. Held as a FIELD on a wrapping class (locals are rejected by E08256). See Q158 for the canonical field-on-class pattern.

CLOSED BY DEFAULT

Built-in generics cannot be extended. Use composition:

  MyList             // CORRECT: wrap a List
    items <- List() of String

See Q45 for List. See Q46 for Dict. See Q47 for Optional. See Q48 for Result. See Q128 for closed collections. See Q158 for MutexLock.

Example

#!ek9
defines module qa.generics.builtin

  defines program

    BuiltinGenericsDemo()
      stdout <- Stdout()

      // === LIST OF T ===

      names <- List() of String
      names += "Alice"
      names += "Bob"
      stdout.println(`List size: ${length names}`)

      // === DICT OF (K, V) ===

      ages <- {"Alice": 30, "Bob": 25}
      stdout.println(`Dict size: ${length ages}`)

      // === OPTIONAL OF T ===

      maybe <- Optional("hello")
      if maybe?
        stdout.println(`Optional has value: ${maybe}`)

      emptyOpt <- Optional() of String
      stdout.println(`Empty optional set: ${emptyOpt?}`)

      // === RESULT OF (OK, ERR) ===

      okResult <- Result("Success", Integer())
      stdout.println(`Result is ok: ${okResult?}`)

      // === MUTEXLOCK OF T ===
      // MutexLock must be a FIELD on a wrapping class — see Q158 and Q213
      // for the canonical pattern. Locals are rejected (E08256).

      stdout.println("MutexLock of T — see Q158 for the field-on-class pattern")

      // === CANNOT EXTEND (CLOSED) ===
      // MyList extends List of String  // ERROR: not open
      // Use composition instead:
      //   MyList
      //     items as List of String

      stdout.println("Built-in generics are closed, use composition")

Common mistakes

E06020 — List takes one type parameter T. Providing two type arguments does not match the generic definition. See ek9 -h E06020 for details.

Incorrect:

names <- List() of (String, Integer)

Correct:

names <- List() of String
Other ways to ask this
  • What parameterized types come with EK9?
  • Which generic containers does EK9 have?
  • Can I extend built-in generic types in EK9?

Coming from another language?

Java: ArrayList<T>, HashMap<K,V>, Optional<T> are all open to extension. Python: list, dict are open. Rust: Vec<T>, HashMap<K,V> cannot be inherited (no inheritance). Go: slices and maps are built-in, no generics before 1.18. Kotlin: List<T>, Map<K,V> are interfaces. EK9: List, Dict, Optional, Result, MutexLock are closed generic types, use composition pattern.

Keywords: absent, built-in, dict, error, generic, guard, iterator, list, mutexlock, ok, optional, parameterized, priorityqueue, result, safe, type-parameter