Mutability, References and Imperative Code

Idiomatic F# limits mutation to small, local scopes (often for performance) and exposes immutable interfaces.

let mutable count = 0
count <- count + 1

// Closures can't capture mutable locals: use ref cells
let makeCounter () =
    let count = ref 0
    fun () ->
        count.Value <- count.Value + 1
        count.Value
let next = makeCounter ()
next (), next ()                               // (1, 2)

// Mutable record fields and class properties
type Account = { mutable Balance: decimal }

// Arrays are mutable; lists, maps, and sets aren't
let buffer = Array.zeroCreate<byte> 1024

// Imperative loops with early exit via exceptions or recursion (no break)
let findIndex pred (arr: 'T[]) =
    let mutable result = -1
    let mutable i = 0
    while result = -1 && i < arr.Length do
        if pred arr[i] then result <- i
        i <- i + 1
    result