Ocaml ML系列编译器是否对尾部调用进行过复杂的优化?

Ocaml ML系列编译器是否对尾部调用进行过复杂的优化?,ocaml,sml,tail-recursion,ml,Ocaml,Sml,Tail Recursion,Ml,我(相信)以下函数定义是尾部递归的: fun is_sorted [] = true | is_sorted [x] = true | is_sorted (x::(y::xs)) = if x > y then false else is_sorted (y::xs) 简单地说,它相当于下面的声明 fun is_sorted [] = true | is_sorted [x] = true | is_sorted (x::(y::xs

我(相信)以下函数定义是尾部递归的:

fun is_sorted [] = true
  | is_sorted [x] = true
  | is_sorted (x::(y::xs)) =
    if x > y
       then false
       else is_sorted (y::xs)
简单地说,它相当于下面的声明

fun is_sorted [] = true
  | is_sorted [x] = true
  | is_sorted (x::(y::xs)) = 
    (x <= y) andalso (is_sorted (y::xs))
fun已排序[]=true
|_排序为[x]=true吗
|是否已排序(x::(y::xs))=

(x如果我将您的第二个函数转换为OCaml,我会得到以下结果:

let rec is_sorted : int list -> bool = function
| [] -> true
| [_] -> true
| x :: y :: xs -> x < y && is_sorted xs
正如您所看到的,这段代码中没有递归调用,只有一个循环

(但其他人的观点是正确的,OCaml在复杂的分析方面做的并不多。这个特殊的结果似乎非常简单。)

注意

A andalso B
相当于

if A then B else false

SML语言定义甚至是这样定义的。因此,B处于尾部位置。不需要进行任何花哨的优化。

我可以告诉你,上次我阅读OCaml生成的程序集时,
fun x->let r=g x in r
中的调用并没有被编译为尾部调用。我不这么认为。Haskell对编译器的回复相当多进行这种优化。但是OCaml的理念是将这种优化级别留给开发人员,通常它的编译器只是直接根据开发人员编写的内容进行编译。在我看来,您的函数在列表中得到了错误的答案。
[3,4,2,3,4]
很好,我将修改定义,以便递归调用是正确的“is_sorted(y::xs)”编译器完全了解
的短路性质,并且可能首先将其转换为等效的条件。我希望任何半体面的编译器都能正确处理尾部调用,特别是因为它对编译器编写者来说只增加很少的工作。
if A then B else false