Module C1.02
let bindings, immutability & shadowing
A name binds a value, and that binding does not change.
In F#, let binds a name to a value, and that binding is
immutable by default — the name cannot be reassigned. Reaching for a new value means writing
a new binding, not overwriting the old one. This module separates three ideas that look alike and are not:
binding and immutability, shadowing (rebinding a name introduces a fresh
binding, it does not mutate the old value), and mutability for the cases that genuinely call
for it (mutable with the <- assignment operator). Three
dives, each with valid, runnable F#.
One keyword, three distinctions
The whole module turns on a single line of F#. A let binding names a value;
because it is immutable, the name and the value stay welded together for the rest of that scope. Three
questions follow, and each is a dive.
The first dive establishes the rule: what a let binding is, why it is immutable,
and the exact error the compiler returns when code tries to reassign one. The second dive handles the
common surprise — writing let x = x + 1 looks like mutation but is a new binding
that shadows the old one, which is unchanged. The third dive covers the escape hatch:
when a value must change in place, let mutable with <-
makes it assignable, kept deliberate and local. Select a dive below for its one-line summary.
The three dives · select one
A let binds a name to a value, and that binding cannot be reassigned. Trying to do so is a compile error, FS0027.
Open this dive · or pick another above
One keyword, three distinctions: a binding holds, shadowing replaces a name without touching the old value, and mutability changes a value in place only where you ask for it.
The three dives
Read them in order. Each stands on valid, idiomatic F# — the exact syntax, the real compiler error, and the behaviour the language defines — and names what it adds to a working mental model of bindings.
let bindings & immutability
What a let binding is, why it is immutable, and the FS0027 error when code reassigns one.
- rulea name cannot be reassigned
Shadowing
Rebinding a name is a new binding that shadows the old one; the original value is unchanged.
- scopeshadowing is not mutation
Mutability when you need it
let mutable with the <- operator changes a value in place — kept deliberate and local.
- mutableassignment with <-
References
Sources
- Microsoft — F# documentation — let bindings, values, and the mutable keyword.
- The F# language specification — the precise rules for bindings, scope, and mutable values.
- The F# Software Foundation — the language's home and its functional-first defaults.
Related in this course
- C1.02.1 — let bindings & immutability — the rule and its compile error.
- C1 — F# Language — the chapter this module sits in.
- Elixir — immutability — the same default, told for the BEAM.