Skip to main content
Klar

Operators

Complete reference for all operators in Klar.

Arithmetic Operators

Standard Arithmetic

OperatorDescriptionExample
+Additiona + b
-Subtractiona - b
*Multiplicationa * b
/Divisiona / b
%Remaindera % b
- (unary)Negation-x
let a: i32 = 10
let b: i32 = 3

let sum: i32 = a + b       // 13
let diff: i32 = a - b      // 7
let prod: i32 = a * b      // 30
let quot: i32 = a / b      // 3
let rem: i32 = a % b       // 1
let neg: i32 = -a          // -10

Overflow Handling Operators

Klar provides explicit overflow handling:

OperatorDescriptionOn Overflow
+%Wrapping additionWraps around
-%Wrapping subtractionWraps around
*%Wrapping multiplicationWraps around
+|Saturating additionClamps to max/min
-|Saturating subtractionClamps to max/min
*|Saturating multiplicationClamps to max/min
let max: i32 = 2147483647

// Wrapping (two's complement wrap)
let wrapped: i32 = max +% 1   // -2147483648

// Saturating (clamps at limits)
let saturated: i32 = max +| 1  // 2147483647 (stays at max)

Comparison Operators

OperatorDescriptionExample
==Equala == b
!=Not equala != b
<Less thana < b
<=Less than or equala <= b
>Greater thana > b
>=Greater than or equala >= b
let a: i32 = 10
let b: i32 = 20

let eq: bool = a == b      // false
let ne: bool = a != b      // true
let lt: bool = a < b       // true
let le: bool = a <= b      // true
let gt: bool = a > b       // false
let ge: bool = a >= b      // false

Logical Operators

Klar uses keywords for logical operations:

OperatorDescriptionExample
andLogical ANDa and b
orLogical ORa or b
notLogical NOTnot a
let a: bool = true
let b: bool = false

let and_result: bool = a and b  // false
let or_result: bool = a or b    // true
let not_result: bool = not a    // false

Short-Circuit Evaluation

and and or use short-circuit evaluation:

// b() is not called if a is false
let result: bool = a() and b()

// b() is not called if a is true
let result: bool = a() or b()

Bitwise Operators

OperatorDescriptionExample
&Bitwise ANDa & b
|Bitwise ORa | b
^Bitwise XORa ^ b
~Bitwise NOT~a
<<Left shifta << n
>>Right shifta >> n
let a: i32 = 0b1100  // 12
let b: i32 = 0b1010  // 10

let and_bits: i32 = a & b    // 0b1000 = 8
let or_bits: i32 = a | b     // 0b1110 = 14
let xor_bits: i32 = a ^ b    // 0b0110 = 6
let not_bits: i32 = ~a       // Bitwise NOT
let left: i32 = a << 2       // 0b110000 = 48
let right: i32 = a >> 2      // 0b0011 = 3

Assignment Operators

OperatorDescriptionEquivalent
=Assignment-
+=Add assigna = a + b
-=Subtract assigna = a - b
*=Multiply assigna = a * b
/=Divide assigna = a / b
%=Remainder assigna = a % b
var x: i32 = 10

x += 5   // x = 15
x -= 3   // x = 12
x *= 2   // x = 24
x /= 4   // x = 6
x %= 4   // x = 2

Range Operators

OperatorDescriptionExample
..Exclusive range0..5 (0,1,2,3,4)
..=Inclusive range0..=5 (0,1,2,3,4,5)
// Exclusive: end is not included
for i: i32 in 0..5 {
    println("{i}")  // 0, 1, 2, 3, 4
}

// Inclusive: end is included
for i: i32 in 0..=5 {
    println("{i}")  // 0, 1, 2, 3, 4, 5
}

Optional/Error Operators

OperatorDescriptionExample
?Error propagationvalue?
??Null coalescingopt ?? default
!Force unwrapopt!
// Error propagation
fn read() -> Result#[Data, Error] {
    let content: string = read_file(path)?  // Returns Err if fails
    return Ok(parse(content))
}

// Null coalescing
let value: i32 = maybe_int ?? 0  // Use 0 if None

// Force unwrap (panics if None/Err)
let value: i32 = some_value!

Member Access Operators

OperatorDescriptionExample
.Field/method accessobj.field
::Enum variant constructionEnum::Variant
[]Index accessarr[i]
// Field access
let x: i32 = point.x

// Method call
let len: i32 = string.len()

// Enum variant
let color: Color = Color::Red

// Index
let first: i32 = array[0]

Type Conversion Operators

OperatorDescriptionExample
.as#[T]Safe conversionx.as#[i64]
.to#[T]Fallible conversions.to#[i32]
.trunc#[T]Truncating conversionx.trunc#[i8]
let x: i32 = 42

// Safe widening
let y: i64 = x.as#[i64]

// Fallible conversion
let n: ?i32 = "42".to#[i32]

// Truncating (may lose data)
let small: i8 = x.trunc#[i8]

Operator Precedence

From highest to lowest precedence:

  1. Unary: -, not, ~
  2. Multiplication: *, /, %
  3. Addition: +, -
  4. Shifts: <<, >>
  5. Bitwise AND: &
  6. Bitwise XOR: ^
  7. Bitwise OR: |
  8. Comparisons: <, <=, >, >=
  9. Equality: ==, !=
  10. Logical AND: and
  11. Logical OR: or
  12. Range: .., ..=
  13. Assignment: =, +=, etc.

Use parentheses for clarity:

// Precedence might be unclear
let result: i32 = a + b * c

// Clearer with parentheses
let result: i32 = a + (b * c)

Operator Traits

Operators are implemented through traits:

OperatorTrait
==, !=Eq
<, <=, >, >=Ordered

Implement these traits on your types to use the operators:

struct Point {
    x: i32,
    y: i32,
}

impl Point: Eq {
    fn eq(self: Point, other: Point) -> bool {
        return self.x == other.x and self.y == other.y
    }
}

// Now == works for Point
let p1: Point = Point { x: 1, y: 2 }
let p2: Point = Point { x: 1, y: 2 }
let equal: bool = p1 == p2  // true

Next Steps