What operations does List support in EK9?

← Getting Started · Ref: Q88

EK9 Lists support a rich set of operations beyond basic add/remove: membership testing, reverse, comparison, copy/merge, and conversion to String/JSON.

MEMBERSHIP TESTING

Three ways to check if an item is in a list:

  numbers contains 3             operator syntax
  "Alice" is in names            natural language syntax
  "Zara" is not in names         negated form

All three return Boolean. The 'is in' and 'is not in' operators read like English.

REVERSE

  reversed <- numbers.reverse()   returns a new reversed list

The original list is unchanged.

COMPARISON

Lists compare element by element:

  [1, 2, 3] == [1, 2, 3]    true (same elements, same order)
  [1, 2, 3] <> [4, 5, 6]    true (different elements)

COPY AND MERGE

  copied :=: original       deep copy of original into copied
  target :~: "Eve"           merge a single item into target
  target :~: otherList       merge all items from otherList into target

Copy (:=:) replaces the contents entirely. Merge (:~:) appends to existing contents.

STRING AND JSON CONVERSION

  $numbers                   string representation: [1, 2, 3]
  $$numbers                  JSON array: [1, 2, 3]

The $$ operator converts any list to a JSON array.

HASHCODE

  hash <- #? numbers         integer hash of the list contents

EMPTY LIST IS SET (NOT UNSET)

Critical semantics: an empty list IS set. List() of String creates a valid, set, empty list. An empty list is meaningful, not unknown. Only explicit unSet() makes a list unset.

See Q45 for List basics (creation, add, remove, access). See Q89 for stream pipelines (filter, map, collect). See Q29 for the tri-state model (absent/unset/set). See Q130 for mutating vs non-mutating operator deep dive. See Q186 for merge collections. See Q187 for reverse list.

Example

defines module qa.list.operations

  defines program
    ListOperationsDemo()
      stdout <- Stdout()

      // === MEMBERSHIP TESTING ===

      numbers <- [1, 2, 3, 4, 5]
      minTagLength <- 3
      hasThree <- numbers contains minTagLength
      stdout.println(`Contains 3: ${hasThree}`)

      names <- ["Alice", "Bob", "Charlie"]

      if "Alice" is in names
        stdout.println("Found Alice")

      if "Zara" is not in names
        stdout.println("Zara not found")

      // === REVERSE ===

      reversed <- numbers.reverse()
      stdout.println(`Reversed: ${reversed}`)
      stdout.println(`Original unchanged: ${numbers}`)

      // === COMPARISON ===

      l1 <- [1, 2, 3]
      l2 <- [1, 2, 3]
      l3 <- [4, 5, 6]

      stdout.println(`l1 == l2: ${l1 == l2}`)
      stdout.println(`l1 <> l3: ${l1 <> l3}`)

      // === COPY AND MERGE ===

      copied <- List() of Integer
      copied :=: numbers
      stdout.println(`Copied: ${copied}`)

      // Merge single item
      names :~: "Dave"
      stdout.println(`After merge item: ${names}`)

      // Merge list into list
      extras <- ["Eve", "Frank"]
      names :~: extras
      stdout.println(`After merge list: ${names}`)

      // === STRING AND JSON CONVERSION ===

      asString <- $numbers
      stdout.println(`As string: ${asString}`)

      stdout.println(`As JSON: ${$ numbers}`)

      // === HASHCODE ===

      hash <- #? numbers
      stdout.println(`Hash: ${hash}`)

      // === EMPTY LIST IS SET ===

      emptyList <- List() of String
      require emptyList?
      require emptyList is empty
      stdout.println(`Empty list isSet: ${emptyList?}`)
      stdout.println(`Empty list isEmpty: ${emptyList is empty}`)

Common mistakes

E50060 — List has no reversed() method. The correct EK9 method is reverse(). Use 'ek9 -h List' to see the full API. See ek9 -h E50060 for details.

Incorrect:

reversed <- numbers.reversed()

Correct:

reversed <- numbers.reverse()
Other ways to ask this
  • How do I check if an item is in a list in EK9?
  • How do I copy or merge lists in EK9?
  • How do I compare lists or convert them to JSON in EK9?

Coming from another language?

Java: Collections.reverse() modifies in place, List.contains() for membership, no 'is in' syntax, equals() for comparison, no built-in JSON. Python: 'in' operator for membership, reversed() returns iterator, == for comparison, json.dumps() for JSON. JavaScript: includes() for membership, reverse() mutates, JSON.stringify() for JSON. Rust: contains() for membership, == via PartialEq, serde for JSON. Go: no contains (manual loop), no operator overloading. EK9: 'contains', 'is in', 'is not in' for membership, reverse() returns new list, == and <> for comparison, :=: copy, :~: merge, $ string, $$ JSON.

Keywords: beginner, copy, contains, list, is in, hashcode, comparison, operations, first, start, is not in, membership, json, intro, reverse, merge, string