First, I acknowledge the possibility that this question could be a duplicate; just let me know.
I\'m curious what the general \"best practice\" is for those situatio
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!