Why does EK9 reject discarded operator return values?

← Code Quality · Ref: Q777

EK9 distinguishes between mutating operators (which change state) and computational operators (which return new values). If you call a computational operator and discard the result, the computation was pointless — dead code.

MUTATING OPERATORS (return Void — side-effect IS the purpose)

  price += tax      // Modifies price in place
  count++           // Increments count
  target :=: source // Copies source into target

COMPUTATIONAL OPERATORS (return values — the VALUE is the purpose)

  total <- price + tax    // Must capture the result
  isEqual <- a == b       // Must use the Boolean
  len <- length name      // Must use the Integer

THIS EXAMPLE

The calculate() function captures the result of every operator. The mutation removes the capture, leaving a bare operator call that discards its result.

See Q238 for operator overview. See Q239 for comparison operators. See Q310 for code quality checks.

Example

defines module qa.codequality.discardedreturn

  defines class

    Calculator

      add() as pure
        ->
          left as Float
          right as Float
        <- rtn as Float: left + right

      multiply() as pure
        ->
          left as Float
          right as Float
        <- rtn as Float: left * right

      default operator ?

  defines program

    ShowCalculation()
      stdout <- Stdout()
      calculator <- Calculator()
      total <- calculator.add(100.0, 15.0)
      stdout.println($total)

Common mistakes

E11051 — Calling a pure method that returns a value and discarding the result is dead code. The method has no side effects, so without capturing the return value the call achieves nothing. See ek9 -h E11051 for details.

Incorrect:

      calculator.add(100.0, 15.0)
      stdout.println("done")

Correct:

      total <- calculator.add(100.0, 15.0)
      stdout.println($total)
Other ways to ask this
  • What triggers E11050 discarded operator return?
  • Why must I capture the result of an operator?
  • What is the difference between += and + in EK9?

Coming from another language?

Java: silently discards return values of any expression statement. Python: silently discards return values. Rust: warns about unused results with #[must_use]. Go: compile error for unused function returns but not operators. Kotlin: no enforcement. EK9: compile error for discarded computational operator returns — dead code is not allowed.

Keywords: dead, E11050, result, code, discarded, computational, operator, return, mutating, capture