这两个递归ocaml函数有什么区别?

SKL*_*LAK 5 recursion stack ocaml overflow

let rec x1() = x1();()
let rec x2() = x2();;
Run Code Online (Sandbox Code Playgroud)

调用x1();; 生成堆栈溢出,同时调用x2();; 导致程序无限期运行.两个功能有什么区别?

gau*_*amc 7

let rec x1() = x1();()
Run Code Online (Sandbox Code Playgroud)

这个函数不是尾递归的.它自称为x1(); 当此调用返回时,该函数将返回一个unit().

let rec x2() = x2();;
Run Code Online (Sandbox Code Playgroud)

这个功能在最后调用自己; 因此编译器可以执行尾调用优化 - 这意味着递归函数调用永远不会耗尽所有堆栈空间.

这个页面解释了尾递归:http://ocaml.org/learn/tutorials/if_statements_loops_and_recursion.html#Tailrecursion - 它是函数式编程语言使用的一种基本技术,因此我们可以使用递归来实现循环而不会耗尽内存.

当我阅读Smashing The Stack For Fun和Profit时,我首先了解了进程堆栈; 我仍然认为它对进程堆栈的所有内容有最好的描述.