Why are OCaml function arguments evaluated right-to-left?

Yes indeed, @yoriyuki’s explanation above is correct. The right-to-left evaluation order is key to making the bytecode interpreter (which is still based on the ZINC design) efficient, more precisely to making curried functions almost as efficient as n-ary function. Evaluating an expression pushes it to the stack, and reducing a function pops an argument from the stack, so evaluating arguments from right to left puts values on the stack in the correct order so that the following applications (several in the case of curried functions, fun x -> fun y -> ...) consume arguments from left to right. (Left-to-right would require a FIFO structure to push arguments to, rather than a stack machine, but a stack makes access to recently-defined value faster so it’s typically a better choice for expressions.)

That said, there is no problem with evaluation order if you use monads with pure terms, that is if 'a m is really a pure term whose value describe an effectful computation that returns an 'a – this is what monads were invented for. The reason why you reject an operator (>>) : unit m -> a m -> a m is not that the monadic effects in a m would be executed before those of unit m (this does not depend on the language evaluation order), but because you use a library (such as Lwt or Asyc) that uses a monadic interface but still performs impure side-effects when evaluating values at monadic type.

13 Likes