OCaml - Why doesn't the function change its output?

218 views Asked by At

My professor showed us this code today but I can't seem to understand the result of it:

# let a = 2;;
val a : int = 2
# let f = fun x -> fun y -> if x = y then a + 2 else a - 10;;
val : f 'a -> 'a -> int = <fun>
# f 1 (2 - 1);;
- : int = 4
# let a = 18;;
val a : int = 18
# f 1 (2 - 1);;
- : int = 4

??? So basically, I expect to see this result:

- : int = 20

Why isn't this the output?

1

There are 1 answers

4
Bergi On

It is because let a did introduce a new variable with the same name, but the function still refers to the one in its scope - it's a closure, and the variable it closed over is a constant. It does not look up the variable name dynamically in the scope from where it is called.

You can achieve the behaviour you expected by storing a mutable reference in the variable that you can assign to:

# let a = ref 2;;
  let f = fun x -> fun y -> if x = y then !a + 2 else !a - 10;;
  f 1 (2 - 1);;
- : int = 4
# a := 18;;
  f 1 (2 - 1);;
- : int = 20

However, notice that this is generally not desired. Variables should be constant, so that we can argue about the function f always returning either 4 or 8 when it is called, instead of having the result depend on where and when which value was assigned to the reference cell. Avoid them where you can. In this particular example, one could do it like this:

let f a x y = 2 + if x = y then 2 else -10 in
let g = f 2 in
print_int (g 1 (2-1));
let h = f 18 in
print_int (h 1 (2-1));;