I have a question about OCaml: Assume the following function declarations:
let secret x y =
let secret' x y z = x + y - z in
let z = if x mod 2 = 0 then y else x - y
in secret' x z ;;
print_int (secret 3 2 (-5));;
The output will be 9.
Why is the result 9?
Is this the way its calculations are performed?
let secret 3 2 =
let secret' 3 2 z = 3 + 2 - z in
let z = if 3 mod 2 = 0 then 2 else 3 - 2
in secret' 3 1
Why doesn't it stop at secret' 3 1 but instead comes up with the result 9? Computes it secret' 3 1 (-5) = 3 + 1 -(-5) ? Why?
First, let's fix the indentation, as it's quite misleading right now.
let secret x y =
let secret' x y z = x + y - z in
let z = if x mod 2 = 0 then y else x - y in
secret' x z ;;
Same function, but doesn't imply that the local z
is related to the secret'
function. Second, let's remove some of the variable shadowing, because you're calling secret'
with a derived y
(which you call z
in another place but which is different from z
in secret'
), so for the sake of clarity, let's rename those variables.
let secret x y =
let secret' a b c = a + b - c in
let z = if x mod 2 = 0 then y else x - y in
secret' x z ;;
Now we make the call
secret 3 2 (-5)
We have a definition for secret x y
. So we can forget about the third argument for now and just call this function.
(secret 3 2) (-5)
Replace with definition.
((let secret' a b c = a + b - c in let z = if x mod 2 = 0 then y else x - y in secret' x z) 3 2) (-5)
Substitute 3
for x
and 2
for y
.
(let secret' a b c = a + b - c in let z = if 3 mod 2 = 0 then 2 else 3 - 2 in secret' 3 z) (-5)
Simplify z
, since we know its value.
(let secret' a b c = a + b - c in secret' 3 1) (-5)
Now we can partially apply secret'
. We don't have a value for c
yet (we do in the outer expression, but we're not looking there right now). The above is equivalent to
(let secret' a b = fun c -> a + b - c in secret' 3 1) (-5)
Oh look! Suddenly the function takes two arguments. And we have two arguments. Let's apply it. Substitute 3
for a
and 1
for b
.
(fun c -> 3 + 1 - c) (-5)
Hey, look! A function of one argument being applied to one argument. Substitute -5
for c
.
3 + 1 - (-5)
and simplify the arithmetic
9