F#: let mutable vs. ref

I can only support what gradbot said – when I need mutation, I prefer let mutable.

Regarding the implementation and differences between the two – ref cells are essentially implemented by a very simple record that contains a mutable record field. You could write them easily yourself:

type ref<'T> =  // '
  { mutable value : 'T } // '

// the ref function, ! and := operators look like this:
let (!) (a:ref<_>) = a.value
let (:=) (a:ref<_>) v = a.value <- v
let ref v = { value = v }

A notable difference between the two approaches is that let mutable stores the mutable value on the stack (as a mutable variable in C#) while ref stores the mutable value in a field of a heap-allocated record. This may have some impact on the performance, but I don’t have any numbers…

Thanks to this, mutable values that use ref can be aliased – meaning that you can create two values that reference the same mutable value:

let a = ref 5  // allocates a new record on the heap
let b = a      // b references the same record
b := 10        // modifies the value of 'a' as well!

let mutable a = 5 // mutable value on the stack
let mutable b = a // new mutable value initialized to current value of 'a'
b <- 10           // modifies the value of 'b' only!

Leave a Comment