Why does EK9 reject a coalescing expression where both sides are literals?

← Comparison Patterns · Ref: Q1333

EK9 detects when both operands of a coalescing operator (<?, >?, <=?, >=?, ?:, ??) are literal values and raises E08094. Because both sides are known at compile time, the coalescing result is predetermined - the expression is dead code and almost always a copy-paste error or unfinished placeholder.

THE PROBLEM

The coalescing minimum '100 <? 200' always yields 100; the maximum '100 >? 200' always yields 200. Writing this is no different from assigning the answer directly, so the operator serves no purpose.

CORRECT PATTERN

Keep at least one operand a variable or named constant so the result genuinely depends on runtime values:

  best <- onlinePrice <? FLOOR_PRICE
  cap  <- requested >? MAX_LIMIT

If you really want a fixed value, assign it directly: result: 100.

See Q638 for literal-vs-literal comparison detection (E08082). See Q963 for how the <? coalescing minimum operator works.

Example

defines module qa.comparison.constant.coalescing

  defines constant

    FLOOR_PRICE <- 50

    MAX_LIMIT <- 200

  defines function

    <?-
      Correct: coalescing minimum between a variable and a named constant.
      Replacing onlinePrice with a literal would trigger E08094.
    -?>
    bestPrice() as pure
      -> onlinePrice as Integer
      <- best as Integer: onlinePrice <? FLOOR_PRICE

    <?-
      Correct: coalescing maximum between a variable and a named constant.
    -?>
    cappedRequest() as pure
      -> requested as Integer
      <- cap as Integer: requested >? MAX_LIMIT

  defines program

    ConstantCoalescingDemo()
      stdout <- Stdout()

      stdout.println(`Best price: ${bestPrice(75)}`)
      stdout.println(`Best price: ${bestPrice(40)}`)
      stdout.println(`Capped: ${cappedRequest(150)}`)
      stdout.println(`Capped: ${cappedRequest(250)}`)

Common mistakes

E08094 — Both operands of the <? coalescing minimum are literals, so the result is fixed at compile time (always 100) - dead code that usually means a copy-paste slip or unfinished placeholder. Keep at least one side a variable or named constant, or assign the intended value directly. See ek9 -h E08094 for details.

Incorrect:

best as Integer: 100 <? 200

Correct:

best as Integer: onlinePrice <? FLOOR_PRICE
Other ways to ask this
  • What triggers E08094 when using <? or >? with two literal values?
  • Why can't I write 100 <? 200 in EK9?
  • How do I fix a coalescing minimum or maximum that has a predetermined result?

Coming from another language?

Java: has no coalescing minimum/maximum operator and no detection of predetermined expressions; Math.min(100, 200) compiles silently. Kotlin/Swift: chained ?: and ?? with two constants compile without warning. Rust: clippy flags some absurd constant comparisons but not coalescing. EK9: compile-time error (E08094) whenever both coalescing operands are literals.

Keywords: coalescing, literal, predetermined, E08094, comparison, minimum, dead, code, constant, maximum, pattern