How do I work with Boolean values?
← Getting Started · Ref: Q30
In most languages, a Boolean is either true or false. In EK9, a Boolean has three states: true, false, and unset. An unset Boolean is neither true nor false. It means 'not yet determined' or 'we do not know yet'. This is a fundamental difference.
Consider a medical test result. 'Negative' (false) and 'we have not run the test yet' (unset) are completely different states. In Java, Python, or Go, an uninitialised boolean defaults to false, which silently conflates 'no' with 'unknown'. EK9 makes the distinction explicit.
CREATING BOOLEANS
ready <- true failed <- false unknown <- Boolean()
The first two are set. The third exists but is unset. Use ? to check:
if ready? stdout.println("ready has a value") if unknown? stdout.println("this will not print")
LOGICAL OPERATORS
EK9 provides four logical operators:
and Logical conjunction: true and false gives false or Logical disjunction: true or false gives true xor Exclusive or: true xor true gives false, true xor false gives true not Logical negation: written as 'not' keyword ~ Complement operator: ~true gives false, ~false gives true
These operators work on set Boolean values. If either operand is unset, the result is unset. This propagates the 'unknown' state correctly rather than silently treating it as false.
COMPARISON OPERATORS
== Equality: true == true gives true <> Inequality: true <> false gives true <=> Comparison: returns Integer for ordering
OTHER OPERATORS
$ String conversion: $ready gives "true" $$ JSON conversion :=: Copy assignment :^: Replace assignment :~: Merge assignment += Accumulate (logical or) + Addition (logical or, pure) | Pipeline operator
BOOLEAN FROM STRING
You can construct a Boolean from a String:
fromText <- Boolean("true") invalid <- Boolean("maybe")
If the string is not 'true' or 'false', the Boolean becomes unset rather than throwing an exception. This follows the tri-state pattern: invalid input produces an unset value you can check with ?.
WHY TRI-STATE MATTERS
In Java: boolean defaults to false. Did the user decline, or did we forget to ask?
In Python: bool defaults to False. Is the flag off, or was it never configured?
In Go: bool defaults to false. Is the check complete with a negative result, or was it never performed?
In JavaScript: undefined, null, and false are all falsy but mean different things.
EK9 eliminates this ambiguity. Boolean() is unset. Boolean(true) is true. Boolean(false) is false. Three distinct states, three distinct meanings.
For locale-specific Boolean display, see Q44 (How does the Locale type work in EK9?).
See also Q29 (What is the default value of an unset variable?) for the full tri-state model. See Q47 for how the ? operator is used with Optional types. See Q244 for boolean and bitwise operators (and, or, xor, ~).
Example
defines module qa.boolean.values defines program BooleanDemo() stdout <- Stdout() // Three states ready <- true failed <- false unknown <- Boolean() stdout.println(`ready: ${ready}, is set: ${ready?}`) stdout.println(`failed: ${failed}, is set: ${failed?}`) stdout.println(`unknown is set: ${unknown?}`) // Logical operators both <- ready and failed either <- ready or failed exclusive <- ready xor failed flipped <- ~ready stdout.println(`and: ${both}, or: ${either}`) stdout.println(`xor: ${exclusive}, complement: ${flipped}`) // Boolean from String fromText <- Boolean("true") invalid <- Boolean("maybe") stdout.println(`from text: ${fromText?}, invalid: ${invalid?}`) // Guarded assignment unknown :=? true stdout.println(`unknown after guard: ${unknown}`)
Common mistakes
E07620 — EK9 logical operators require Boolean operands. Using an Integer where a Boolean is expected triggers E07620 — type incompatibility. Use a comparison operator to produce a Boolean. See ek9 -h E07620 for details.
Incorrect:
both <- ready and 42
Correct:
both <- ready and failed
Other ways to ask this
- What logical operators does EK9 have?
- Can a Boolean be unset in EK9?
- How does Boolean tri-state work in EK9?
Coming from another language?
Java: boolean defaults to false, Boolean wrapper can be null (NPE risk). Python: bool defaults to False, truthy/falsy rules for other types. Go: bool defaults to false, no nullable bool. JavaScript: undefined/null/false all falsy with different semantics. Rust: bool is true/false, Option<bool> for tri-state. C#: bool defaults to false, Nullable<bool> for tri-state. EK9: Boolean has three states (true, false, unset), logical operators (and, or, xor, not, ~), unset propagates through operations.
Keywords: bool, unset, migrate, not, tri-state, xor, tristate, true, logical, and, false, intro, boolean, or, first, beginner, complement, start