OCaml没有任何递归检查吗?

7 ocaml functional-programming tail-recursion

我最近一直在玩OCaml,并立即做了我最喜欢的事情来检查VM /编译器的开发情况,并写了一个递归程序:

let rec f i =
    Printf.eprintf "i = %d\n" i;
    f(i+1);;

let () =
    f 0;;
Run Code Online (Sandbox Code Playgroud)

该程序按预期运行,但是,递归永远不会中断,事实上,我让这个程序运行了几次(大约30分钟),将stderr重定向到File,以避免堵塞我的终端.检查完文件后,当我注意到文件大约是7*GB*大时,我感到很震惊!

怎么会这样?OCaml没有任何递归限制吗?

Pas*_*uoq 14

您应该查找有关尾调用优化的信息.

要回答你的问题,有一个堆栈限制,如果堆栈增长,你的程序就可以达到.

你不应该期望用你的程序达到它,而不是你期望在C程序中的无用表达式中除以零,一旦编译就总是产生除零:编译器可能会删除无用的除法.在您的示例中,编译器删除了无用的堆栈溢出.

实际上,它比这更进一步.正如维基百科页面上所解释的那样,OCaml和大多数函数式语言都保证尾调用转换完成,因此在使用递归时可以依赖它.

  • 另外一点想想:由于递归是函数式语言中的标准循环结构,OCaml中的递归限制将等于循环在C或Python中运行的次数的限制. (8认同)