据我所知,所有现代命令式编程语言都支持过程可以调用自身的递归。并非总是如此,但是我无法通过Google的快速搜索找到任何困难的事实。所以我的问题是:
哪些语言从一开始就不支持递归?何时添加了这种支持?
据我所知,所有现代命令式编程语言都支持过程可以调用自身的递归。并非总是如此,但是我无法通过Google的快速搜索找到任何困难的事实。所以我的问题是:
哪些语言从一开始就不支持递归?何时添加了这种支持?
Answers:
我不确定COBOL是否这样做(当然一次也没有),但是我也无法想象有人在乎什么。
Fortran自Fortran 90起就有,但要求您使用recursive
关键字告诉它子例程是递归的。
PL / I几乎相同-支持递归,但是您必须明确告诉它哪些过程是递归的。
我怀疑还有更多。当您开始研究时,禁止递归是IBM在其语言设计中所做的主要工作,原因很简单,因为IBM(360/370/3090 / ...)大型机不支持硬件堆栈。当大多数语言来自IBM时,它们大多禁止递归。现在它们都来自其他地方,总是可以使用递归(尽管我应该补充一点,其他一些机器,特别是原始的Cray 1,也没有对堆栈的硬件支持)。
notably the original cray 1
因此,您不需要递归来克隆恐龙吗?我想这真的取决于我们猴子在树上摇摆。
维基百科说:
像Fortran这样的早期语言最初并不支持递归,因为变量是静态分配的,并且返回地址的位置也是如此。
http://en.wikipedia.org/wiki/Subroutine#Local_variables.2C_recursion_and_re-entrancy
FORTRAN 77不允许递归,而Fortran 90不允许(必须明确声明递归例程)。
大多数FORTRAN 77编译器都允许递归,有些(例如DEC)要求使用编译器选项(请参见编译器选项一章)。严格遵守Fortran 77标准的GNU g77根本不允许递归。
一些用于小型微控制器的c编译器不支持递归,大概是因为它们的堆栈大小非常有限。
这取决于您所说的“ 支持 ”。为了支持递归,您需要一个堆栈,该堆栈在每次重新进入时都会重新实例化局部变量。
即使该语言没有局部变量的概念,如果它具有“子例程”的概念并且可以管理相同变量(也称为数组)之间的索引,则可以在每次进入/退出时增加/减少全局索引函数的功能,并通过它访问一个或多个数组的成员。
我不知道这是否可以称为“支持”。事实是,我使用ZX-Spectrum BASIC编写了递归函数,就像我在Fortran77和COBOL中所做的那样……总是有这个技巧。
汇编语言不直接支持递归-您必须“自己动手”,通常是将参数压入机器堆栈中。
CALL
指令,它会在跳转到子例程之前自动将IP推入堆栈,还有一条指令会将RET
返回地址弹出到IP中。您没有理由不能CALL
拥有自己的入口点。
void f() { f(); }
是递归的。