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:
floored <- onlinePrice >? FLOOR_PRICE (a floor: never below FLOOR_PRICE) cap <- requested <? MAX_LIMIT (a cap: never above 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 maximum (>?) gives the larger operand, so it acts as a FLOOR. Replacing onlinePrice with a literal would trigger E08094. -?> flooredPrice() as pure -> onlinePrice as Integer <- floored as Integer: onlinePrice >? FLOOR_PRICE <?- Correct: coalescing minimum (<?) gives the smaller operand, so it acts as a CAP. -?> cappedRequest() as pure -> requested as Integer <- cap as Integer: requested <? MAX_LIMIT defines program ConstantCoalescingDemo() stdout <- Stdout() stdout.println(`Floored price: ${flooredPrice(75)}`) stdout.println(`Floored price: ${flooredPrice(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 200) - 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:
floored as Integer: 100 >? 200
Correct:
floored 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: comparison, E08094, predetermined, literal, coalescing, pattern, maximum, constant, code, dead, minimum