According to the OCaml manual
let pattern_1 = expr_1 and … and pattern_n = expr_n in expr.... evaluatesexpr_1 … expr_nin some unspecified order ....`
Does any compiler or rutnime for OCaml take advantage of the order being unspecified?
For example, ocamlopt and ocamlc+ocamlrun in practice use a distinct evaluation order for function arguments and I was wondering if something similar arises for let ... and.
I wasn't able to find any case where the evaluation order isn't left-to-right, here's some code that prints 123 whether I use ocaml or ocamlopt:
let p = Printf.printf "%d%!"
let rec spin = function
| 0 -> ()
| n -> spin (n - 1)
let () =
let x0 = spin 99999999
and x1 = p 2
and x2 = p 3 in
let _ = x0, x1, x2 in
()
First of all. There might be many compilers and some may not be open-sourced and/or released, so it is impossible to answer your question in the way it is stated.
In general, a common practice when defining the semantics of a language is to use statements in their weakest forms, i.e., to leave as much space for maneuver to the compiler. Since the least constrained is the input the more options will have a compiler to produce a more optimal program.
Speaking of the mainstream OCaml distribution, there is no difference1 in the compiled code between
let p1 and p2 .. and pN in eandlet p1 in let p2 in ... let pN in eprovided thatp1,...,pNare data independent2. The compiler will produce the same lambda code for both expressions, meaning that even the bytecode will be the same.More specifically, both expressions will be translated to the lambda form
(let (p1 p2 ... pN) e), even if there are data dependencies between the patterns (the compiler will rename all variables, ensuring that all variables are fresh). Since translating to lambda is the first step in the compilation (apart from parsing and typing, which is not strictly a part of a compilation process) the information about the form of the let expression that you used in the source code is lost, so the later stages of compilation, especially the instruction scheduling, will not be able to utilize this hint.To be honest, the compiler doesn't really need this hint from the developer. The OCaml compiler is clever enough to perform the data and side-effect analysis to re-arrange the terms as much as needed. So the main use of the
let p1 and ... pN in eform is to communicate to the readers of the code, i.e., to our fellow programmers, that patternsp1andpNare independent and could be read independently. Since this vastly reduces the cognition burden (each expression now has a much smaller context) it makes your program more readable. Even with side-effectful expressions, when you writeYou explicitly say to the reader that there's no difference in which order
fandgare executed, therefore they are independent functions.1) You can check this by adding the
-dlambdaoption toocamlopt(orocamlc).2) If they have dependencies, it means that they are different programs, so the compiler must produce different code. In other words, there shouldn't be any optimizations.