How do I use streams and stream pipelines in EK9?

← Getting Started · Ref: Q89

EK9 lists use cat | pipe | collect syntax for stream pipelines, replacing Java Streams, Python comprehensions, and JS array methods.

BASIC PATTERN: cat source | operations | terminal

  cat numbers | filter by isEven | collect as List of Integer
  cat numbers | map with doubleIt | collect as List of Integer
  cat numbers | collect as Integer

FILTER BY

  evens <- cat numbers | filter by isEven | collect as List of Integer

Predicate must be pure, returning Boolean.

MAP WITH

  doubled <- cat numbers | map with doubleIt | collect as List of Integer

COLLECT AS

  List of T collects elements. Integer reduces by summation.

DIRECT OUTPUT

  cat numbers | map with intToString > stdout

TEE FOR SIDE EFFECTS

  cat numbers | tee in sideEffect | collect as List of Integer

COMBINING: stages chain naturally. Streams replace loops with break/continue (EK9 has none).

See Q45 for List basics. See Q51 for abstract pipeline functions. See Q52 for dynamic functions. See Q53 for closures. See Q54 for Predicate/Comparator/UnaryOperator. See Q55 for delegates. See Q59 for pipelines. See Q64 for for-range. See Q65 for for-in. See Q88 for List operations. See Q120 for sorting. See Q122 for custom collect. See Q124 for group by. See Q125 for head/tail/skip. See Q133 for tee/uniq. See Q235 for stream reference. See Q236 for custom iterators. See Q237 for streams vs loops. See Q265 for fluent API. See Q275 for AI break/continue. See Q284 for first match.

Example

defines module qa.list.streams

  defines function

    isEven() as pure
      -> num as Integer
      <- rtn as Boolean: num mod 2 == 0

    doubleIt() as pure
      -> num as Integer
      <- rtn as Integer: num * 2

    intToString() as pure
      -> num as Integer
      <- rtn as String: $num

  defines program
    ListStreamsDemo()
      stdout <- Stdout()

      numbers <- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
      stdout.println(`Numbers: ${numbers}`)

      // === FILTER BY ===

      // Select even numbers
      evens <- cat numbers | filter by isEven | collect as List of Integer
      stdout.println(`Evens: ${evens}`)

      // === MAP WITH ===

      // Double each number
      doubled <- cat numbers | map with doubleIt | collect as List of Integer
      stdout.println(`Doubled: ${doubled}`)

      // Transform to strings
      asStrings <- cat numbers | map with intToString | collect as List of String
      stdout.println(`As strings: ${asStrings}`)

      // === COLLECT AS REDUCTION ===

      // Sum all numbers
      total <- cat numbers | collect as Integer
      stdout.println(`Sum: ${total}`)

      // === COMBINED PIPELINE ===

      // Filter then map
      doubledEvens <- cat numbers | filter by isEven | map with doubleIt | collect as List of Integer
      stdout.println(`Doubled evens: ${doubledEvens}`)

      // === DIRECT OUTPUT ===

      // Pipe directly to stdout
      cat numbers | map with intToString > stdout

Common mistakes

E07520 — The 'filter by' pipeline stage requires a predicate function returning Boolean. A function returning any other type triggers E07520 — filter function must return Boolean. See ek9 -h E07520 for details.

Incorrect:

filter by doubleIt

Correct:

filter by isEven

E07830 — Each pipeline stage must accept the type produced by the previous stage. A type mismatch between stages triggers E07830 — pipeline type mismatch. See ek9 -h E07830 for details.

Incorrect:

map with intToString | collect as List of Integer
      stdout.println(`As strings: ${asStrings}`)

Correct:

map with intToString | collect as List of String
      stdout.println(`As strings: ${asStrings}`)
Other ways to ask this
  • How do I filter and map a list in EK9?
  • What is the cat pipe collect pattern in EK9?
  • How do stream pipelines work with lists in EK9?
  • What replaces for loops with break in EK9?
  • What is the EK9 equivalent of Java Stream API?

Coming from another language?

Java: Stream API, verbose Collectors. Python: list comprehensions. JS: .filter().map().reduce(). Go: manual loops. EK9: cat | filter by | map with | collect as, unified pipe syntax.

Keywords: migrate, start, transform, lazy, async, fluent, sequence, filter, first, parallel, functional, cat, beginner, concurrency, intro, chain, map, stream, pipe, pipeline, collect, tee, stdout