Ocaml中参数的评估顺序

Ole*_*leg 2 ocaml arguments functional-programming function

我想知道为什么ocaml从右到左评估调用,是FP原则还是根本不重要FP语言?

快速举例:

let rec qs = function
    | [] -> []
    | h::t -> let l, r = List.partition ((>) h) t in
    List.iter (fun e -> print_int e; print_char ' ') l; Printf.printf " <<%d>> " h;
    List.iter (fun e -> print_int e; print_char ' ') r; print_char '\n';
    (qs l)@(h::qs r)
Run Code Online (Sandbox Code Playgroud)

在我的例子中,(qs r)首先评估调用,然后(qs l)我预计它将是另外的.

# qs [5;43;1;10;2];;
1 2  <<5>> 43 10 
10   <<43>> 
     <<10>> 
     <<1>> 2 
     <<2>> 
- : int list = [1; 2; 5; 10; 43]
Run Code Online (Sandbox Code Playgroud)

编辑:

来自https://caml.inria.fr/pub/docs/oreilly-book/html/book-ora029.html

在Objective CAML中,未指定参数的评估顺序.碰巧,今天Objective CaL的所有实现都从左到右评估参数.如果语言的未来版本修改了实现,那么使用此实现功能可能会变得非常危险.

Jef*_*eld 6

OCaml中未指定对函数参数的求值顺序.

这在本手册的第6.7节中有记录.

实质上,这给系统(编译器或解释器)提供了最大的自由度,以便以某种方式有利的顺序来计算表达式.这意味着您(作为OCaml程序员)必须编写不依赖于评估顺序的代码.

如果您的代码纯粹是功能性的,那么它的行为不能依赖于顺序.因此,只有在编写带效果的代码时才需要小心.

更新

如果您关心订单,请使用let:

let a = <expr1> in
let b = <expr2> in
f a b
Run Code Online (Sandbox Code Playgroud)

或者,更一般地说:

let f = <expr0> in
let a = <expr1> in
let b = <expr2> in
f a b
Run Code Online (Sandbox Code Playgroud)

更新2

值得一提的是,上面引用的这本书是在2002年出版的.从那以后,很多都发生了变化,包括语言的名称.更现实的资源是Real World OCaml.