How do boolean and bitwise operators work in EK9?
← Operators and Expressions · Ref: Q244
EK9 uses the SAME operator names for both Boolean logic and Bits manipulation. The compiler resolves which implementation to use based on the operand types.
SHARED OPERATORS
The 'and', 'or', 'xor' operators work on BOTH Boolean and Bits types. All are pure, take 1 argument, and return a value.
For Boolean:
result <- true and false result <- true or false result <- true xor true
For Bits:
mask <- 0b1100 and 0b1010 combined <- 0b1100 or 0b1010 toggled <- 0b1100 xor 0b1010
NEGATION (~)
The ~ operator works on Boolean (logical NOT) and Bits (bitwise NOT). Numbers use unary - for negation, not ~.
notTrue <- ~ true flipped <- ~ 0b1100
BIT SHIFT OPERATORS (<< and >>)
The << and >> operators are Bits-only. They shift bits left or right. Both are pure, take 1 Integer argument, and return a new Bits value.
shifted <- 0b0001 << 3 result <- 0b1000 >> 2
Bits values grow as needed with left shift. Right shift discards bits.
BITS ARE NOT INTEGERS
Bits are ordered collections of individual bits. They are NOT integers. You cannot add Bits or use them in arithmetic. They support: and, or, xor, ~ (NOT), << (shift left), >> (shift right), length, ==, <>, $.
BITS LITERALS
Bits literals use the 0b prefix:
flags <- 0b010011 mask <- 0b111100
See Q30 for Boolean basics. See Q40 for Bits type. See Q238 for the complete operator set. See Q240 for arithmetic operators.
Example
defines module qa.operators.booleanbitwise defines program BooleanBitwiseDemo() stdout <- Stdout() // === BOOLEAN LOGIC === a <- true b <- false stdout.println(`and: ${a and b}`) stdout.println(`or: ${a or b}`) stdout.println(`xor: ${a xor b}`) stdout.println(`not: ${~ a}`) // === BITWISE OPERATIONS (same syntax!) === mask1 <- 0b1100 mask2 <- 0b1010 stdout.println(`Bits and: ${mask1 and mask2}`) stdout.println(`Bits or: ${mask1 or mask2}`) stdout.println(`Bits xor: ${mask1 xor mask2}`) stdout.println(`Bits not: ${~ mask1}`) // === BIT SHIFT === oneBit <- 0b0001 shifted <- oneBit << 3 stdout.println(`Shift left: ${shifted}`) wide <- 0b1000 narrow <- wide >> 2 stdout.println(`Shift right: ${narrow}`) // === BITS ARE NOT INTEGERS === flags <- 0b010011 stdout.println(`Flags length: ${length flags}`) stdout.println(`Flags equal: ${flags == 0b010011}`)
Common mistakes
E07620 — Boolean negation in EK9 uses the ~ operator, not ! which is the factorial operator for Integer. The ! operator is not defined on Boolean. See ek9 -h E07620 for details.
Incorrect:
stdout.println(`not: ${a!}`)
Correct:
stdout.println(`not: ${~ a}`)
Other ways to ask this
- What is the difference between boolean and bitwise operators in EK9?
- How do shift operators work on Bits in EK9?
- Does EK9 use the same syntax for boolean and bitwise operations?
Coming from another language?
Java: && || for boolean, & | ^ for bitwise, different syntax for same concepts. Python: and or not for boolean, & | ^ ~ for bitwise, different syntax. Rust: && || for boolean, & | ^ for bitwise, ! for both not. Go: && || for boolean, & | ^ for bitwise, different syntax. Kotlin: && || for boolean, and or xor for bitwise on Int. JavaScript: && || for boolean, & | ^ for bitwise, different syntax. EK9: 'and' 'or' 'xor' '~' for BOTH Boolean and Bits (same syntax, type-based dispatch), << >> for Bits only.
Keywords: expression, left, operator, xor, mask, bitwise, bits, logic, flag, binary, and, boolean, not, right, shift, or, negate