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