How do I choose the right collection type in EK9?

← Collections and Data Structures · Ref: Q126

EK9 provides five main collection and container types. Each serves a distinct purpose.

LIST

Ordered, indexed collection of elements:

  items <- [1, 2, 3]

Use when: you need ordered sequences, indexed access, iteration, stream pipelines.

DICT

Key-value lookup collection:

  ages <- {"Alice": 30, "Bob": 25}

Use when: you need fast lookup by key, associative data, configuration maps.

PRIORITYQUEUE

Bounded, automatically sorted collection:

  top <- PriorityQueue(item).withComparator(comp).withSize(5)

Use when: you need the top-N items, maintaining sorted order with a size limit.

OPTIONAL

Contains zero or one value:

  name <- Optional("Alice")

Use when: a value may or may not exist, safe null alternative.

RESULT

Contains either a success value or an error:

  result <- Result(value) or Result(error)

Use when: an operation can fail and you want to handle both cases explicitly.

DECISION GUIDE

Need a sequence of items? -> List
Need key-value lookup? -> Dict
Need top-N with automatic ordering? -> PriorityQueue
Might have zero or one value? -> Optional
Operation might succeed or fail? -> Result

See Q45 for List details. See Q46 for Dict details. See Q47 for Optional. See Q48 for Result. See Q121 for PriorityQueue. See Q129 for safe Dict key access. See Q130 for mutating vs non-mutating operators on collections. See Q182 for collection empty check.

Example

defines module qa.collections.choosing

  defines program

    ChoosingCollectionDemo()
      stdout <- Stdout()

      // === LIST: ORDERED SEQUENCE ===

      tasks <- ["write code", "run tests", "deploy"]
      tasks += "review"
      stdout.println(`Tasks: ${tasks}`)

      // === DICT: KEY-VALUE LOOKUP ===

      config <- {"host": "localhost", "port": "8080"}
      host <- config.getOrDefault("host", "unknown")
      stdout.println(`Host: ${host}`)

      // === PRIORITYQUEUE: TOP-N ===

      comparator <- () extends Comparator of Integer as pure function (r:=? t1 <=> t2)
      scores <- PriorityQueue(95).withComparator(comparator).withSize(3)
      scores += 87
      scores += 92
      scores += 78
      scores += 99
      topScores <- scores.list()
      stdout.println(`Top 3 scores: ${topScores}`)

      // === OPTIONAL: MAYBE A VALUE ===

      name <- Optional("Alice")
      if name?
        stdout.println(`Name: ${name}`)

      // === RESULT: SUCCESS OR ERROR ===

      result <- Result() of (String, Integer)
      if result?
        stdout.println(`Got: ${result}`)
      else
        stdout.println("No result")

Common mistakes

E50060 — EK9 Dict has no get() method. Use getOrDefault(key, default) which always returns a usable value. See ek9 -h E50060 for details.

Incorrect:

host <- config.get("host")

Correct:

host <- config.getOrDefault("host", "unknown")

E50060 — EK9 List has no .add() method. Use the += operator to add elements. See ek9 -h E50060 for details.

Incorrect:

tasks.add("review")

Correct:

tasks += "review"

E50060 — PriorityQueue has no .toArray() method. Use .list() to get entries as a sorted List. See ek9 -h E50060 for details.

Incorrect:

topScores <- scores.toArray()

Correct:

topScores <- scores.list()

E50060 — EK9 does not have toString(). Use string interpolation or the $ operator. See ek9 -h E50060 for details.

Incorrect:

stdout.println(tasks.toString())

Correct:

stdout.println(`Tasks: ${tasks}`)

E50060 — EK9 does not have toString(). Use string interpolation or the $ operator. See ek9 -h E50060 for details.

Incorrect:

stdout.println(host.toString())

Correct:

stdout.println(`Host: ${host}`)
Other ways to ask this
  • When should I use List vs Dict vs PriorityQueue in EK9?
  • What collection types are available in EK9?
  • How do I decide between List, Dict, Optional, and Result in EK9?

Coming from another language?

Java: ArrayList, HashMap, PriorityQueue, Optional, no built-in Result. Python: list, dict, no PriorityQueue built-in (heapq module), no Optional. JavaScript: Array, Map/Object, no PriorityQueue/Optional/Result. Rust: Vec, HashMap, BinaryHeap, Option, Result. Go: slices, maps, no generics until 1.18, no Option/Result. EK9: List, Dict, PriorityQueue, Optional, Result all generic and type-safe with consistent operator syntax.

Keywords: safe, error, guard, priority, ok, container, optional, list, collection, result, decision, type, absent, choose, dict, data-structure