原话是
进程和过程之间的区别可能令人困惑的一个原因是,大多数公共语言(包括 Ada、Pascal 和 C)的实现都设计为这样一种方式,即任何递归过程的解释都会消耗大量内存,而内存量会随着过程调用的数量,即使所描述的过程原则上是迭代的。因此,这些语言只能通过使用特殊用途的“循环结构”来描述迭代过程,例如 do、repeat、until、for 和 while。
我不熟悉C语言,Java或C#呢?他们也是这样吗?为什么?
注意:我以为作者在谈论不同语言的能力。但实际上它只是编译器的不同实现。
他基本上是想说这些语言的编译器不能进行尾递归消除。长话短说,他错了(或者无论如何都过度概括了——我想“大多数实现”已经足够狡猾的措辞了,它在技术上可能是正确的,尽管充其量是误导)。虽然我当然不能保证所有其他语言的每个编译器都会消除尾递归,但毫无疑问,至少有一些 C 和 C++ 编译器(例如,英特尔 C++、gcc/g++)可以并且将会。我没有检查过,但考虑到 GNAT(Gnu Ada 编译器)使用相同的优化器以及它们的 C 和 C++ 编译器,我的直接猜测是它也可以进行尾递归消除。
自从我使用 Pascal 以来已经有足够长的时间了,我无法对它做出明智的评论——我的直接猜测是“不”,但这与语言本身几乎没有关系,主要归结为事实目前对 Pascal 的大多数使用都可以追溯到 Borland,而且他们似乎从未在优化代码生成方面投入太多精力。
你问:C#呢?
C# 与 Java 类似,但与大多数 C/C++ 或 ADA 实现不同,它编译为中间语言,然后进一步编译,通常在运行时由“即时编译器”进行编译。
在撰写本文时,C# 编译器不会执行尾递归消除,但 JIT 可以。
它与编译器的实现无关。
你错过了他试图提出的重点,即流程和程序之间的区别。一个过程可能是递归的,即使它正在实现的底层过程原则上是迭代的;和递归过程消耗堆栈。