Why must stream functions have exactly one parameter in EK9?

← Streams and Pipelines · Ref: Q824

Most EK9 stream operators, such as filter, map and uniq, require a function with exactly one parameter matching the stream element type. The exception is 'sort by', whose comparator takes TWO parameters of the element type and returns an Integer.

THE RULE

A filter predicate has a single parameter:

  isPositive() as pure
    -> amount as Integer       // ONE parameter: correct for filter
    <- rtn as Boolean: amount > 0

A function with two parameters cannot be used by filter, map or uniq:

  isInRange() as pure
    ->
      lo as Integer            // TWO parameters: wrong for filter
      hi as Integer
    <- rtn as Boolean: lo < hi

THE CODES FOR A WRONG PARAMETER COUNT

- filter or map with 0 or 2+ parameters: E06300
- uniq with 0 or 2+ parameters: E07460
- sort by with 1 parameter: E07470
- sort by with 2 parameters but a non-Integer return: E07550

WHY THIS RULE

Stream operators call the function once per element (or once per pair of elements for sort), passing the current element as the argument. A function with a different number of parameters cannot receive it.

HOW TO FIX

- Use a single parameter matching the stream type (two for a sort comparator)
- If you need additional context, use a dynamic function that captures extra values

See Q812 for stream errors. See Q126 for stream reference.

Example

defines module qa.streams.function.arity

  defines function

    isPositive() as pure
      -> amount as Integer
      <- rtn as Boolean: amount > 0

    isInRange() as pure
      ->
        lowerBound as Integer
        upperBound as Integer
      <- rtn as Boolean: lowerBound < upperBound

  defines program

    StreamFunctionArityDemo()
      stdout <- Stdout()

      // === CORRECT: filter with single-parameter predicate ===
      cat [3, -1, 5, -2, 8]
        | filter by isPositive
        > stdout

Common mistakes

E07460 — Stream uniq requires a function with exactly one parameter matching the stream type. isInRange has two parameters so cannot receive a single stream element. See ek9 -h E07460 for details.

Incorrect:

        | uniq isInRange

Correct:

        | filter by isPositive
Other ways to ask this
  • What is E07460 FUNCTION_MUST_HAVE_SINGLE_PARAMETER?
  • Why does my stream filter function fail with parameter count error?
  • How many parameters can a stream function have in EK9?

Coming from another language?

Java: Stream.filter() takes Predicate<T> (single arg), sorted() takes a two-argument Comparator. Python: filter(func, iterable) passes one item. Rust: .filter(|x| ...) takes one reference. Go: no built-in stream, but range gives one item. EK9: compile-time enforcement that stream functions have the parameter count the operator needs: one for filter, map and uniq, two for a sort comparator.

Keywords: stream, single, function, uniq, sort, E07460, parameter, filter, arity