Why does EK9 reject non-Boolean values in if conditions?
← Operators and Expressions · Ref: Q937
EK9 requires Boolean expressions in Boolean contexts. Unlike C or JavaScript, there is no implicit truthiness conversion.
BOOLEAN CONTEXT REQUIRES BOOLEAN
Conditions in if, while, and other control flow must evaluate to Boolean:
- 'if count > 0' is CORRECT: a comparison produces Boolean
- 'if name?' is CORRECT: ? produces Boolean
- 'while isActive' is CORRECT: isActive is Boolean
NO IMPLICIT CONVERSION
These fail because the value is not Boolean:
if count // ERROR: Integer is not Boolean if name // ERROR: String is not Boolean while connectionObj // ERROR: object is not Boolean
USE ? FOR SET CHECKS
To check if a non-Boolean value is set, use the ? suffix operator:
- 'if count?' asks whether count is set and returns Boolean
- 'if name?' asks whether name is set and returns Boolean
USE COMPARISONS FOR VALUE CHECKS
- 'if count > 0' - a numeric comparison returns Boolean
- 'if length name > 0' - checks that the String has content
A TYPE OF YOUR OWN
If a type you write has a natural true/false reading, give it 'operator #^ as pure <- rtn as Boolean: ...'. Every condition - if, while, a ternary, require and assert - then accepts it, and the compiler inserts the promotion. It is explicit in the type's own definition and single-step (a type whose '#^' gives Integer is not a condition), so it is not truthiness.
This eliminates an entire class of bugs from truthy/falsy confusion in JavaScript and Python.
See Q877 for isSet operator. See Q936 for ? suffix position. See Q30 for Boolean operators.
Example
defines module qa.operators.booleancontext defines program BooleanContextDemo() stdout <- Stdout() //? operator produces Boolean — correct userName <- String() userName :=? "Alice" if userName? stdout.println(`Name is set: ${userName}`) //Comparison produces Boolean — correct score <- Integer() score :=? 5 if score? if score > 0 stdout.println(`Score is positive: ${score}`) //Compound Boolean expressions — correct threshold <- 10 if score? if score > 0 and score < threshold stdout.println("Score in range")
Common mistakes
E07540 — A non-Boolean value like the Integer 'score' cannot be used as an 'if' condition — use a comparison such as 'score > 0'. See ek9 -h E07540 for details.
Incorrect:
if score stdout.println(`Score is positive: ${score}`)
Correct:
if score > 0 stdout.println(`Score is positive: ${score}`)
Other ways to ask this
- What triggers E07540 in EK9?
- Can I use an Integer as a condition in EK9?
- Why won't if count work when count is an Integer?
Coming from another language?
JavaScript: if (count) truthy for non-zero. Python: if count truthy for non-zero/non-empty. C: if (ptr) truthy for non-null. Java: Boolean required, no implicit conversion. Rust: Boolean required, like EK9. EK9: Boolean required, use ? for isSet check or comparisons.
Keywords: context, implicit, truthiness, E07540, boolean, conversion, type, condition