Author: Christian.Queinnec@lip6.fr

## Order of Evaluation of Arguments

In a pure functional language, the order of evaluation of the arguments does not matter. As there is no modification of memory state and no interruption of the calculation, there is no risk of the calculation of one argument influencing another. On the other hand, in Objective CAML, where there are physically modifiable values and exceptions, there is a danger in not taking account of the order of evaluation of arguments. The following example is specific to version 2.04 of Objective CAML for Linux on Intel hardware:

    # let new_print_string s = print_string s; String.length s ;;
    val new_print_string : string -> int = <fun>
    # (+) (new_print_string "Hello ") (new_print_string "World!") ;;
    World!Hello - : int = 12

The printing of the two strings shows that the second string is output before the first.
It is the same with exceptions:

    # try (failwith "function") (failwith "argument") with Failure s -> s;;
    - : string = "argument"

If you want to specify the order of evaluation of arguments, you have to make local declarations forcing this order before calling the function. So the preceding example can be rewritten like this:

    # let e1 = (new_print_string "Hello ")
     in let e2 = (new_print_string "World!")
     in (+) e1 e2 ;;
    Hello World!- : int = 12

In Objective CAML, the order of evaluation of arguments is not specified. As it happens, today all implementations of Objective CAML evaluate arguments from left to right. All the same, making use of this implementation feature could turn out to be dangerous if future versions of the language modify the implementation.
We come back to the eternal debate over the design of languages. Should certain features of the language be deliberately left unspecified---should programmers be asked not to use them, on pain of getting different results from their program according to the compiler implementation? Or should everything be specified---should programmers be allowed to use the whole language, at the price of complicating compiler implementation, and forbidding certain optimizations?