Mantis Bug Tracker

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0006136OCamlOCaml documentationpublic2013-08-22 15:312014-09-23 17:34
Assigned To 
PlatformOSOS Version
Product Version 
Target Version4.03.0+devFixed in Version 
Summary0006136: Function call evaluation order varies more than manual allows
DescriptionThe manual says that OCaml application is multi-argument

   The expression expr argument1 … argumentn evaluates the expression expr and
   those appearing in argument1 to argumentn.

and that the order of evaluation of the arguments and the function is

   The order in which the expressions expr, argument1, …, argumentn are
   evaluated is not specified.

However, the time of the actual call is specified: it takes place after the
function expression and all the argument expressions have been evaluated:

   The expression expr must evaluate to a functional value f, which is then
   applied to the values of argument1, …, argumentn.

In practice, there's more variation in the behaviour; it shows up when a
function performs an effect after receiving arguments. Here's an example
showing the different behaviour between ocamlc and ocamlopt, and with known
and unknown functions:

First, the example. (The function syntactically takes two arguments, but its
type 'a -> 'b -> 'a allows more.)

   $ cat
   let f g x = ignore (failwith "called f"); g

   let g x = x

   let h = f g 2 (failwith "third argument")

With ocamlc the function is never called, since the evaluation of the third
argument raises an exception:

   $ ocamlc -o call && ./call
   Fatal error: exception Failure("third argument")

With ocamlopt the function is called before receiving all three arguments, so
the third argument is never evaluated:

   $ ocamlopt -o call && ./call
   Fatal error: exception Failure("called f")

Here's a variation of the example where f is no longer statically visible:

   $ cat
   let f g x = ignore (failwith "called f"); g

   let g x = x

   let h f =
     f g 2 (failwith "third argument")

   let _ = h f

Now ocamlopt evaluates all three arguments before calling the function:

   $ ocamlopt -o call2 && ./call2
   Fatal error: exception Failure("third argument")
TagsNo tags attached.
Attached Files

- Relationships

-  Notes
doligez (administrator)
2013-08-22 23:34

Simplifying the examples a little bit:

let pr x = Printf.printf "%s\n%!" x;;
let f = fun x -> ignore (pr "f"); fun y -> ();;
f (pr "1") (pr "2");;

With ocamlc, we get the expected "2 1 f"; with ocamlopt, we get "1 f 2".

- Issue History
Date Modified Username Field Change
2013-08-22 15:31 yallop New Issue
2013-08-22 23:34 doligez Note Added: 0010228
2013-08-22 23:34 doligez Status new => confirmed
2013-08-22 23:34 doligez Target Version => 4.01.1+dev
2014-05-25 20:20 doligez Target Version 4.01.1+dev => 4.02.0+dev
2014-07-24 20:20 doligez Target Version 4.02.0+dev => 4.02.1+dev
2014-09-04 00:25 doligez Target Version 4.02.1+dev => undecided
2014-09-23 17:34 doligez Target Version undecided => 4.03.0+dev

Copyright © 2000 - 2011 MantisBT Group
Powered by Mantis Bugtracker