F# Let Bindings Guide — Immutability, Scope, and Variable Declaration
In this tutorial, you will learn about F# Let Bindings Guide. We cover key concepts, practical examples, and best practices to help you master this topic.
F# let bindings create immutable values by default -- variables cannot change after assignment, encouraging Functional Programming patterns where data flows through transformations rather than mutations.
Basic Bindings
// Immutable by default
let x = 10
// x <- 20 // ERROR: x is immutable
// Type inference
let name = "Alice" // string
let age = 30 // int
let pi = 3.14159 // float
let isActive = true // bool
// Explicit type annotation
let count: int = 42
let greeting: string = "Hello"
Mutable Variables
// Explicit mutable
let mutable counter = 0
counter <- 5 // OK with <-
counter <- counter + 1
printfn "%d" counter // 6
Shadowing
// Shadowing creates a new binding
let x = 5
printfn "%d" x // 5
let x = x + 3 // new binding, not mutation
printfn "%d" x // 8
// Original x is unchanged
let shadowed = x // 8
Scope
module ScopeExample
let global = "module level"
let myFunction () =
let local = "function level"
if true then
let inner = "block level"
printfn "%s" inner // OK
// printfn "%s" inner // ERROR: out of scope
printfn "%s" local // OK
Common Mistakes
1. Forgetting mutable
Trying to reassign an immutable binding with <- causes a compile error.
2. Using = instead of <-
= is for binding, <- is for assignment. x = 5 is a comparison, not assignment.
3. Confusing shadowing with mutation
let x = x + 1 creates a new binding. The original value is not modified.
FAQ
{{< faq question="Why are values immutable by default?" >}} Immutability eliminates entire categories of bugs (unexpected state changes, race conditions) and enables safer concurrent programming. {{< /faq >}}
{{< faq question="Can I use mutable collections?" >}}
Yes. ResizeArray<T>(), Dictionary<K,V>, and arrays are mutable. But prefer immutable List, Map, and Set.
{{< /faq >}}
{{< faq question="What does let return?" >}}
let bindings return unit () at the module level. In expressions, let ... in ... returns the value of the in expression.
{{< /faq >}}
What's Next
Now learn about F# functions -- pipes, composition, and partial application.
| Topic | Description | Link |
|---|---|---|
| Functions | Pipes and composition | {{< ref "04-functions" >}} |
| Discriminated Unions | Custom types | {{< ref "05-discriminated-unions" >}} |
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro