假设您的 Algol 方言不支持递归,但支持高阶函数。我们还能实现你的例子吗?当然可以!
int foo_aux(int i, Func cont)
{
if( i>10 ) {
return 10;
} else {
cout<<i; // side effect bad!
return cont(i+1, cont); // no recursion
}
}
int foo(int i)
{
return foo_aux(i, [] (int i, Func cont) -> int { return foo_aux(i,cont) });
}
假设您尝试做同样的事情,但您的语言不支持高阶函数也不支持递归。可以模仿吗?一切皆有可能:
std::stack<int> args; // integers can be castable pointers or numbers!
int cont = 2;
while( cont ) {
if( cont == 2 ) { // main
args.push(1)
cont=1; // continuation == foo_aux
} else if ( cont == 1 ) { // foo_aux
int tmp = args.pop();
if( tmp > 10 ) {
args.push(10);
cont=0; // continuation == return/exit
} else {
cout << tmp;
args.push(tmp+1);
// not setting cont == recursion
}
}
}
// do something with the result
return args.pop();
这是一种进行递归的方式,就像在您的初始示例中一样。也许您可以制作一个预处理器(宏)来从像您的示例这样的花哨的东西进行转换,以使其成为用于编译的对象。如果你想将函数作为参数传递,你只需按下数字,你的接收函数需要设置f。
std::stack<int> args; // integers can be castable pointers or numbers!
args.push(2) // bootstrap
int cont = 0;
while( cont = args.pop() ) {
if( cont == 2 ) { // main / foo
args.push(1) // push argument
args.push(1) // push function
} else if ( cont == 1 ) { // foo_aux
int tmp = args.pop();
if( tmp > 10 ) {
args.push(10); // push result
args.push(0); // push exit as continuation
} else {
cout << tmp;
args.push(tmp+1); // push argument
args.push(1); // push self as argument
}
}
}
// do something with the result
return args.pop();
这不支持所谓的向上funarg,因为那时您需要另一个结构来关闭不再在范围内的变量。
那么递归是高阶函数的特例吗?由于可以使用函数索引来模拟函数,因此从编译器的角度来看,可以同时实现函数、递归和高阶函数。这仅意味着可以以相同的方式对函数进行建模。完全有可能制作一个使用不支持高阶函数但支持递归的汇编函数的编译器,并且可以制作一种不支持高阶函数的没有递归的语言,这将能够使用类似 Y combinator 的方式进行递归.除此之外,它们是完全不同的东西。