Junghwan Oh
Junghwan Oh

Reputation: 77

OCaml evaluation of expression, order?

add is a function that is built in to OCaml.

Exp:

# add 5 1;;
- : int = 6

My question: what is the order of evaluation for add 3 (add 5 3)?

# add 3 (add 5 3);;
- : int = 11

Is (add 5 3) evaluated first to 8, then add 3 (8) is evaluated to 11? Or is add 3 evaluated first into a function, and then (add 5 3) is used as a parameter for the function (add 3)?

Thanks.

Upvotes: 4

Views: 982

Answers (3)

Martin Jambon
Martin Jambon

Reputation: 4929

The order of evaluation of arguments in OCaml is unspecified, meaning it can change from one compiler to another.

Let's create a function that's evaluated in two stages:

let mul a =
  Printf.printf "got a: %i\n%!" a;
  fun b ->
    Printf.printf "got b: %i\n%!" b;
    a * b

Running this with utop (or ocaml) shows right-to-left evaluation:

# mul (mul 2 3) (mul 5 7);;
got a: 5
got b: 7
got a: 2
got b: 3
got a: 6
got b: 35
- : int = 210

A let-in can be introduced to force evaluation order, resulting in a different sequence of printfs:

# let mul6 = mul (mul 2 3) in mul6 (mul 5 7);;
got a: 2
got b: 3
got a: 6
got a: 5
got b: 7
got b: 35
- : int = 210

Upvotes: 0

Richard-Degenne
Richard-Degenne

Reputation: 2949

Just to complete Jeffrey's answer, here is a version of add which lets you know when it is executed:

# let add a b =
    Printf.printf "Adding %d and %d...\n" a b;
    a + b;;

val add : int -> int -> int = <fun>

Let's see it in action.

# add (add 1 2) (add 5 8);;

Adding 5 and 8...
Adding 1 and 2...
Adding 3 and 13...

- : int = 16

So here, the second add is evaluated first, but you can't really count on it since it is not specified.

Here is the same example using a local let to force the order:

# let x = add 1 2 in
  add x (add 5 8);;

Adding 1 and 2...
Adding 5 and 8...
Adding 3 and 13...

- : int = 16

And now using partial application.

# let add_3 = add 3 in
  add_3 (add 5 8);;

Adding 5 and 8...
Adding 3 and 13...

- : int = 16

Of course, with (pure) functional programming, order of execution does not matter since everything is immutable. But OCaml is't purely functional, so these little tricks are good to know. :)

Upvotes: 3

Jeffrey Scofield
Jeffrey Scofield

Reputation: 66803

For what it's worth, there's no function named add that's built in to OCaml. (I.e., there's no such symbol in the Pervasives module.)

$ ocaml
        OCaml version 4.06.0

# add;;
Error: Unbound value add

The order of evaluation of a function and its arguments in OCaml is unspecified. So there is no guaranteed order.

This is documented in Section 7.7.1 of the OCaml manual.

If you want an evaluation to happen in a certain order, you can use let to evaluate each subexpression:

# let add a b = a + b;;
val add : int -> int -> int = <fun>
# let temp = add 5 3 in
  add 3 temp;;
- : int = 11
# let tempf = add 3 in
  tempf (add 5 3);;
- : int = 11

Upvotes: 8

Related Questions