It is important to remember that variables in OCaml are immutable.
So why does this happen?
let x = 1;;
val x : int = 1
let x = 2;;
val x : int = 2
x
- : int = 2
Well, it looks like x is changing, but really, it's just nested scopes.
The code above is equivalent to this
let x = 1 in
let x = 2 in
x;;
File "[4]", line 1, characters 4-5:
1 | let x = 1 in
^
Warning 26: unused variable x.
- : int = 2
Another way to think about this is that in the first let expression, we're allocating memory that will always have the value 1. In the second let expression, we're allocating memory that will always have the value 2.
When we reach x, the name means the value assigned to the innermost scope, like we're used to in imperative programming languages.
Variables aren't mutating. We're simply re-declaring it.