Variables and Types
Variable Declarations #
Zolo has three ways to declare variables:
let — Immutable Binding
let x = 10
let name: str = "Zolo"
Once assigned, a let binding cannot be reassigned:
let x = 10
x = 20 // Error: cannot reassign immutable variable
let mut — Mutable Binding
let mut counter = 0
counter = counter + 1 // OK
counter += 1 // OK — compound assignment
const — Constant
const PI: f64 = 3.14159
const MAX_SIZE: int = 1024
Constants must have a value at declaration time and cannot be reassigned.
Type Annotations #
Type annotations are optional — Zolo infers types when possible:
let x = 42 // inferred: int
let y: f64 = 3.14 // explicit: f64
let name = "hello" // inferred: str
let flag = true // inferred: bool
Built-in Types #
| Type | Description | Examples |
|---|---|---|
int |
64-bit integer | 42, -7, 0 |
f64 |
64-bit float | 3.14, -0.5, 1.0 |
str |
String | "hello", "world" |
bool |
Boolean | true, false |
nil |
Null/absence of value | nil |
Compound Types #
Arrays #
let arr: [int] = [1, 2, 3]
let names: [str] = ["Alice", "Bob"]
let empty: [int] = []
Arrays are 0-indexed:
let arr = [10, 20, 30]
print(arr[0]) // 10
print(arr[2]) // 30
Maps #
let scores: {str: int} = { "Alice": 95, "Bob": 87 }
let config = { "host": "localhost", "port": 8080 }
Tuples #
let point: (int, int) = (10, 20)
let pair: (str, int) = ("age", 25)
Optional Types #
The ? suffix makes a type optional (nullable):
let x: int? = 42 // has a value
let y: int? = nil // no value
let name: str? = nil
Function Types #
let callback: fn(int) -> int = |x| x * 2
let predicate: fn(str) -> bool = |s| s.len() > 3
Generic Types #
let map: Map<str, int> = Map.new()
let result: Result<int, str> = Result.Ok(42)
Compound Assignment #
Zolo supports compound assignment operators:
let mut x = 10
x += 5 // x = 15
x -= 3 // x = 12
x *= 2 // x = 24
x /= 4 // x = 6
x %= 5 // x = 1
Shadowing #
You can redeclare a variable with the same name:
let x = 10
let x = x * 2 // shadows the previous x
let x = "hello" // can even change type
Type System Notes #
- Types are checked at compile time — no runtime cost
- The type checker runs during compilation and reports errors with source locations
nilis only allowed for optional types (T?)- Zolo compiles to Lua, so types are erased at runtime