Now that we have references, we can have aliasing. This is when two refs point to the same location in memory
let x = ref 42;;
let y = ref 42;;
val x : int ref = {contents = 42}
val y : int ref = {contents = 42}
Here we have two distinct locations in memory, x and y.
let z = x (* alias *);;
val z : int ref = {contents = 42}
Now, because z is equal to x, it points to the same location in memory.
let () = x := 43;;
!z;;
- : int = 43
Now updating x also updates z. Note that y hasn't changed:
!y;;
!x + !y;;
- : int = 42
- : int = 85
Equaality in refs is weird. Let's say we have two refs:
let r1 = ref 3110;;
let r2 = ref 3110;;
val r1 : int ref = {contents = 3110}
val r2 : int ref = {contents = 3110}
The double equals sign (==) and the exclamation equals sign (!=) check physical equality. That is, they check to see if the two items point to the same location in memory.
r1 == r1;;
r1 != r2;;
- : bool = true
- : bool = true
The single equals sign (=) and the double angle brace (<>) is structural equality. They check to see if they contents of the location are the same.
r1 = r1;;
r1 = r2;;
ref 3110 <> ref 2110;;
- : bool = true
- : bool = true
- : bool = true
You usually want to use single equals. Only use double equals if you want to check if two refs are aliases of each other.