What are the correct patterns for boolean conditions and comparisons?
← Comparison Patterns · Ref: Q689
EK9 enforces clean boolean condition patterns. Conditions must use variables (not literals) and comparisons must have matching types. A ternary expression is typed to a type its branches share: the same type, one branch promoting to the other's type, or their nearest common super or trait - never an invented Any.
NO BOOLEAN LITERALS IN CONDITIONS (E07390)
Using 'true' or 'false' directly in a condition is flagged as a pointless constant:
if true // E07390: always true, dead code stdout.println("always")
The correct form tests a boolean variable:
if isValid stdout.println("valid")
TYPE MATCHING IN COMPARISONS (E07620)
Both sides of a comparison must be compatible types:
if count > 0 stdout.println(count)
This does not compile:
name <- "Steve" if name == 42 // E07620: String has no == for Integer stdout.println(name)
TERNARY TYPES
The result is one of the branches, so it must have a type both branches have. The same type or a subtype gives that type; a branch that promotes to the other's type (Integer to Float) gives the other's type; otherwise the nearest common super class or trait. Branches that share nothing but Any are a compile error:
age <- 20 label <- age >= 18 <- "adult" else 0 // ERROR E50030: String and Integer share only Any
Give both branches one type:
label <- isAdult <- "adult" else "minor"
VARIABLE-BASED CONDITIONS
Store intermediate boolean results in named variables:
isAdult <- age >= adultThreshold isVerified <- account.verified() if isAdult and isVerified grantAccess()
See Q637 for comparison pattern basics. See Q639 for boolean parameter patterns. See Q641 for capture requirements.
Example
defines module qa.comparison.booleanconditions defines constant ADULT_AGE_THRESHOLD <- 18 SENIOR_AGE_THRESHOLD <- 65 MINIMUM_BALANCE <- 100.0 defines function <?- Correct: boolean conditions use variables, not literals. Named intermediates make intent clear. -?> classifyCustomer() as pure -> customerAge as Integer accountBalance as Float <- category as String: "standard" isAdult <- customerAge >= ADULT_AGE_THRESHOLD isSenior <- customerAge >= SENIOR_AGE_THRESHOLD hasMinBalance <- accountBalance >= MINIMUM_BALANCE if isSenior and hasMinBalance category: "premium senior" else if isAdult and hasMinBalance category: "premium" else if isAdult category: "standard" else category: "junior" <?- Correct: comparisons use matching types. Integer compared with Integer, String with String. -?> compareItems() as pure -> itemName as String itemCount as Integer targetName as String targetCount as Integer <- isMatch as Boolean: false nameMatches <- itemName == targetName countSufficient <- itemCount >= targetCount isMatch: nameMatches and countSufficient defines program BooleanConditionPatternsDemo() stdout <- Stdout() stdout.println(classifyCustomer(70, 500.0)) stdout.println(classifyCustomer(25, 50.0)) stdout.println(classifyCustomer(15, 200.0)) matched <- compareItems(itemName: "widget", itemCount: 10, targetName: "widget", targetCount: 5) stdout.println(`Match: ${matched}`)
Common mistakes
E07620 — Both sides of a comparison must be compatible types. Comparing String with Integer is a type mismatch. See ek9 -h E07620 for details.
Incorrect:
nameMatches <- itemName == targetCount
Correct:
nameMatches <- itemName == targetName
E50060 — String has no toUpperCase() method in EK9. Use upperCase() instead. See ek9 -h E50060 for details.
Incorrect:
classifyCustomer(70, 500.0).toUpperCase()
Correct:
classifyCustomer(70, 500.0)
E50060 — Boolean has no toString() method in EK9; use the $ prefix operator (here via ${...} interpolation) to convert to String. See ek9 -h E50060 for details.
Incorrect:
stdout.println(matched.toString())
Correct:
stdout.println(`Match: ${matched}`)
Other ways to ask this
- What is E07620 type mismatch in comparison?
- What is E07390 boolean literal in condition?
- What type does a ternary expression produce when the branches differ?
- How should boolean conditions be written in EK9?
Coming from another language?
Java: boolean literals in conditions are valid (just warnings from linters). Python: no type checking for comparisons. C: any value in condition. Rust: condition must be bool. EK9: conditions must be boolean variables or expressions, no bare literals, types must match.
Keywords: type, condition, E07390, E07620, ternary, literal, boolean, pattern, comparison