Skip to content

Values and Bindings

Kelvra keeps the expression model small on purpose. The language supports typed integers and floats, booleans, null, strings, grouping, arithmetic, comparison, logical operators, and bitwise operators. See Built-in Types and Casts for the numeric families, literal suffixes, and as conversions.

print((2 + 3) * 4)
print(10 > 3)
print(!false && true)
print(7 & 3)
print(1 << 4)

The current operator surface includes:

  • arithmetic: +, -, *, /
  • comparison and equality: >, >=, <, <=, ==, !=
  • logical operators: !, &&, ||
  • bitwise operators: &, |, ^, ~, <<, >>

Local bindings can be written with explicit types or with local inference.

var count i32 = 10
var message = "kelvra"
const answer = 42
const enabled bool = true

Use const when the binding should not be reassigned. Use var when mutation is part of the design.

Inference works well for local values whose initializer already makes the type obvious.

fn buildCounter() Counter {
var counter = Counter()
return counter
}

Current repo guidance is stricter for public APIs and ambiguous cases:

  • function parameters still need explicit types
  • exported APIs should stay explicit
  • locals inferred from void-producing expressions are rejected

Bindings and index/member targets support assignment and compound assignment.

var total i32 = 10
total += 5
total <<= 1
print(total)

Update operators are also available:

var i i32 = 0
i++
++i
print(i)

Bindings are lexical. Inner scopes can read outer names, and nested functions can capture them.

fn outer() i32 {
var x i32 = 10
fn inner() i32 {
return x + 1
}
return inner()
}

Read Functions and Closures for the closure-specific behavior.