How does EK9 detect redundant Boolean comparisons and logical tautologies?

← Code Quality · Ref: Q734

EK9 detects two categories of pointless Boolean logic at compile time.

REDUNDANT BOOLEAN COMPARISON (E08084)

Comparing a Boolean expression directly to true or false is always redundant. 'if flag == true' is identical to 'if flag'. 'if flag == false' is identical to 'if not flag'. The comparison adds nothing and obscures intent.

LOGICAL TAUTOLOGY (E08085)

An expression like 'flag or not flag' is always true regardless of what flag is. Similarly 'flag and not flag' is always false. These are structural tautologies or contradictions that indicate a bug, typically a copy-paste error where two different variables were intended.

CORRECT PATTERNS

Use Boolean values directly in conditions:

  if isReady             not 'if isReady == true'
  if not isDone          not 'if isDone == false'
  if ready or fallback   different variables, not 'ready or not ready'

See Q318 for self-comparison detection. See Q558 for tautological conditions overview. See Q639 for Boolean patterns without literals.

Example

defines module qa.codequality.booleantautology

  defines function

    checkEligibility() as pure
      ->
        hasAccount as Boolean
        isVerified as Boolean
      <- eligible as Boolean: hasAccount and isVerified

    canProceed() as pure
      ->
        ready as Boolean
        fallback as Boolean
      <- proceed as Boolean: ready or fallback

    describeState() as pure
      ->
        active as Boolean
        locked as Boolean
      <- description as String: "unknown"

      if active and not locked
        description: "available"
      else if active
        description: "locked"
      else if not active
        description: "inactive"

  defines program

    BooleanTautologyDemo()
      stdout <- Stdout()

      eligible <- checkEligibility(hasAccount: true, isVerified: true)
      stdout.println(`Eligible: ${eligible}`)

      proceed <- canProceed(ready: false, fallback: true)
      stdout.println(`Proceed: ${proceed}`)

      stdout.println(describeState(active: true, locked: false))
      stdout.println(describeState(active: true, locked: true))
      stdout.println(describeState(active: false, locked: false))

Common mistakes

E50060 — Boolean has no booleanValue() method in EK9. Boolean values are used directly. See ek9 -h E50060 for details.

Incorrect:

eligible <- checkEligibility(hasAccount: true, isVerified: true).booleanValue()

Correct:

eligible <- checkEligibility(hasAccount: true, isVerified: true)

E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.

Incorrect:

stdout.println(describeState(active: true, locked: false).toUpperCase())

Correct:

stdout.println(describeState(active: true, locked: false))
Other ways to ask this
  • What is E08084 redundant Boolean comparison in EK9?
  • What is E08085 logical tautology in EK9?
  • Why does EK9 reject comparing a Boolean to true or false?

Coming from another language?

Java: SpotBugs detects some redundant Boolean comparisons. ESLint has no-constant-binary-expression. Rust: clippy has bool_comparison and logic_bug. Python: pylint detects some redundant comparisons. EK9: mandatory compiler error for both redundant Boolean comparisons and logical tautologies.

Keywords: redundant, contradiction, logic, quality, tautology, E08084, false, E08085, boolean, true, comparison