type dot = {mutable x:int; mutable y:int}
let f (dot1:dot) (dot2:dot) : int =
dot1.x <- 12;
dot2.x <- 26;
dot1.x
I'm not sure what this would evaluate to. I assume it would evaluate to 12 always but the answer key says that it only evaluates to 12 "sometimes". I guess this has to do with whether or not dot1 and dot2 are aliases but I still don't understand why this would matter considering we are only modifying dot1 and accessing the x field of dot1.
Here is a simple example, when the returned value would be 26
not 12
:
# let p = {x=0; y=0};;
val p : dot = {x = 0; y = 0}
# f p p;;
- : int = 26
Here p
is an object that has two mutable fields x
and y
. When applied, function f
gets the same object as dot1
and dot2
, so, both names dot1
and dot2
refer to the same object and, no matter which name you're using, it will lead to the modification of the p
object.
Another example, that doesn't involve any functions, but just let
bound names,
# let p1 = p;;
val p1 : dot = {x = 26; y = 0}
# let p2 = p;;
val p2 : dot = {x = 26; y = 0}
# p1.y <- 1;;
- : unit = ()
# p;;
- : dot = {x = 26; y = 1}
# p2.x <- 11;;
- : unit = ()
# p;;
- : dot = {x = 11; y = 1
As you can see name binding is just a name biding, so it is not creating a new object or anything like this.