Lesson 1: Explicit state and invariants
Before memory, we need to talk about state. An authentication service, shopping cart, or worker is easier to reason about when we know which values may change and which must remain valid.
Goal
In one sentence: distinguish immutable bindings, mutable state, and absence represented by Option<T>.
Code inside main
We will evolve one program inside main, as we would in a real project. We start with explicit state: values that do not change stay immutable; counters and accumulators declare mutability.
import io
func main(): int {
let name: str = "mahua"
let balance: int = 340
let active: bool = true
io.println(name)
io.println(balance)
io.println(active)
return 0
}
main is the program entry point. The body between { and } contains instructions executed in order; return 0 sends the exit status back to the operating system.
Variables are immutable by default. To change a value, use mut:
let mut attempts: int = 0
attempts += 1
If a value does not need to change, keep it immutable. Fewer states for the reader (and the compiler) to track.
Try it
Remove the mut from attempts and see what the compiler says. It will warn you — in a partner-like tone — that you are trying to reassign an immutable value.
Without null, the category “there is nothing here” simply does not exist as a sneaky value. Either a value exists, or you use Option<...> explicitly. Nothing appears out of nowhere at runtime.
That is the first pillar: explicit state and visible invariants from the start. Next, we turn domain rules into functions with verifiable contracts.