ocaml# Question about partial application in OCaml

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?

Solution

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
```

- OCaml equivalent of Python generators
- Compiling multifile projects in Ocaml, leading to Unbound Module error
- Why this recursion example in ocaml doesn't work for negative number?
- OCaml and Opam: unbound module Core
- Figuring out why these types differ when using a catch all in the pattern matching
- Submatrix Ocaml
- Is there a way to `match` on a string that starts with some value?
- Combine two lists while removing duplicates
- Base causes issue with tuple destructuring
- OCaml combine fprintf and sprintf
- deleting duplicates tail recursively in OCaml
- Concurrent write with OCaml Async
- OCaml standard Map vs. Jane Street Core.std Map
- Can't find .ocamlinit file
- Waiting for Writer.write to complete in Caml Async
- Windows support for Jane Street OCaml Core?
- solver_get_unsat_core() in ML (OCaml) API returns empty core
- Debugging with dune
- How to apply a function in an iterable list
- How can I simplify nested pattern matching clauses?
- OCaml - a function which returns all the prefixes of a list
- OCaml Syntax error with if-else block without any information
- Can't compile Hello World in F*
- How to add a library dependency in a dune project that manages the .opam file without an intermediate build error?
- How do I read in lines from a text file in OCaml?
- F# changes to OCaml
- OCaml: Simplest way to merge 2 lists
- How can I change user defined type to int?
- Why does ocaml keep miss understanding type?
- Keepsorted function