Why should I use named constants instead of literal values in comparisons?
← Comparison Patterns · Ref: Q638
EK9 detects when both sides of a comparison are literal values and raises E08082. The result is always a compile-time constant, making the comparison pointless.
THE PROBLEM
Comparing two literals like '18 > 10' always produces the same result. This is dead code: the condition is predetermined. It typically indicates that the developer meant to compare a variable against a constant but accidentally used two constants.
CORRECT PATTERN
Use a named constant on one side and a variable on the other:
if age >= MINIMUM_AGE if temperature > BOILING_POINT if count == EXPECTED_COUNT
NAMED CONSTANTS
Declare constants in a defines constant block:
defines constant MINIMUM_AGE <- 18 MAXIMUM_SPEED <- 120
This gives the literal a meaningful name and avoids magic numbers throughout the code.
WHY NAMED CONSTANTS MATTER
Self-documenting: 'MINIMUM_AGE' explains the intent. Single source of truth: change the value in one place. Avoids E08082: variable vs constant is a genuine comparison. Avoids E11065: magic literals in comparisons.
See Q637 for self-comparison detection. See Q558 for tautological conditions. See Q639 for Boolean comparison patterns.
Example
defines module qa.comparison.namedconstants defines constant MINIMUM_AGE <- 18 MAXIMUM_AGE <- 120 PASSING_SCORE <- 60 SPEED_LIMIT <- 65 BOILING_POINT <- 100.0 FREEZING_POINT <- 0.0 defines function <?- Correct: compares a variable against a named constant. Replacing the variable with a literal would trigger E08082. -?> isAdult() as pure -> age as Integer <- adult as Boolean: age >= MINIMUM_AGE <?- Correct: variable compared against named constant. -?> isPassing() as pure -> score as Integer <- passing as Boolean: score >= PASSING_SCORE <?- Correct: variable compared against named constants for range check. -?> isValidAge() as pure -> age as Integer <- valid as Boolean: age >= MINIMUM_AGE if age > MAXIMUM_AGE valid: false <?- Correct: Float variable compared against named constant. -?> isBoiling() as pure -> temperature as Float <- boiling as Boolean: temperature >= BOILING_POINT <?- Correct: uses named constants for range classification. -?> classifyTemperature() as pure -> temperature as Float <- classification as String: "normal" if temperature >= BOILING_POINT classification: "boiling" else if temperature <= FREEZING_POINT classification: "freezing" defines program NamedConstantsDemo() stdout <- Stdout() stdout.println(`Is 21 adult? ${isAdult(21)}`) stdout.println(`Is 15 adult? ${isAdult(15)}`) stdout.println(`Score 75 passing? ${isPassing(75)}`) stdout.println(`Score 40 passing? ${isPassing(40)}`) stdout.println(`Age 25 valid? ${isValidAge(25)}`) stdout.println(`Age 150 valid? ${isValidAge(150)}`) stdout.println(`100C boiling? ${isBoiling(100.0)}`) stdout.println(`50C boiling? ${isBoiling(50.0)}`) cls <- classifyTemperature(105.0) stdout.println(`105C: ${cls}`)
Common mistakes
E08082 — Comparing two literal values produces a compile-time constant, making the comparison dead code. Compare a variable against a named constant instead. See ek9 -h E08082 for details.
Incorrect:
adult as Boolean: 18 >= 18
Correct:
adult as Boolean: age >= MINIMUM_AGE
E11064 — Using a raw literal 120 in a comparison is a magic literal. Use the named constant MAXIMUM_AGE instead. See ek9 -h E11064 for details.
Incorrect:
if age > 120
Correct:
if age > MAXIMUM_AGE
Other ways to ask this
- Why does EK9 reject literal-vs-literal comparisons?
- Why does EK9 reject comparing two literal values?
- How do I fix a magic number comparison error?
Coming from another language?
Java: no compile-time constant comparison detection. SonarQube flags magic numbers as code smell (optional). Rust: clippy has absurd_extreme_comparisons lint. Go: no magic number detection. Python: pylint magic-value-comparison. C++: -Wtautological-compare for some literal comparisons. EK9: E08082 mandatory error for literal-vs-literal comparison, E11065 for magic literals.
Keywords: migrate, E11065, number, value, comparison, named, E08082, magic, dead, pattern, literal, constant