Why does EK9 reject reassignment in pure functions and parameter reassignment?

← Code Quality · Ref: Q737

EK9 enforces two reassignment restrictions to prevent hidden state changes.

PURE CONTEXT REASSIGNMENT (E08100)

Pure functions cannot use ':=' to reassign variables. Pure functions should compute results, not accumulate state. Use ':=?' (guarded assignment, only sets if unset) or restructure the logic to use return variable assignment.

PARAMETER REASSIGNMENT (E08110)

Function and method parameters are read-only. You cannot reassign a parameter with ':='. Parameters represent the caller's input and modifying them obscures the data flow. Instead, copy the parameter to a local variable and modify the copy.

WHY ENFORCED

These restrictions exist because reassignment creates hidden state changes that are hard to reason about. Pure functions should be deterministic and side-effect free. Parameter immutability prevents confusion about whether modifications are visible to the caller.

See Q678 for purity contracts. See Q635 for pure mutation restrictions.

Example

defines module qa.codequality.pureparamreassign

  defines function

    classifyScore() as pure
      -> score as Integer
      <- label as String: "average"

      highThreshold <- 90
      lowThreshold <- 40

      if score >= highThreshold
        label: "excellent"
      else if score < lowThreshold
        label: "poor"

    doubleValue() as pure
      -> input as Integer
      <- result as Integer: input * 2

    formatName()
      -> rawName as String
      <- formatted as String: rawName

      localName <- rawName
      localName := "Mr. " + localName
      formatted: localName

  defines program

    PureParamReassignDemo()
      stdout <- Stdout()

      stdout.println(classifyScore(95))
      stdout.println(classifyScore(30))
      stdout.println(classifyScore(60))

      stdout.println(`Doubled: ${doubleValue(21)}`)
      stdout.println(formatName("Smith"))

Common mistakes

E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.

Incorrect:

stdout.println(classifyScore(95).toUpperCase())

Correct:

stdout.println(classifyScore(95))

E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.

Incorrect:

stdout.println(formatName("Smith").toUpperCase())

Correct:

stdout.println(formatName("Smith"))

E08110 — Parameters are read-only in EK9. Copy the parameter to a local variable first, then modify the copy. See ek9 -h E08110 for details.

Incorrect:

rawName := "Mr. " + rawName

Correct:

localName <- rawName
      localName := "Mr. " + localName

E50060 — String has no toString() method. classifyScore() already returns a String. See ek9 -h E50060 for details.

Incorrect:

stdout.println(classifyScore(95).toString())

Correct:

stdout.println(classifyScore(95))
Other ways to ask this
  • What is E08100 reassignment in pure context?
  • What is E08110 parameter reassignment in EK9?
  • How do I modify values in a pure function?

Coming from another language?

Java: parameters can be reassigned (but final prevents it). Kotlin: function parameters are val (immutable) by default. Rust: parameters are immutable by default, require mut. Python: parameters can be reassigned freely. Go: parameters can be reassigned freely. EK9: parameters always immutable, pure context bans all reassignment.

Keywords: E08100, restriction, context, pure, parameter, reassignment, quality, E08110, immutable, readonly