$fact = function($n) use (&$fact) {
if ($n === 1) {
return 1;
}
return $fact($n - 1) * $n;
};
echo $fact(5); // =120
Рекурсивный вызов x=f(y) надо заменить на arg[0]=y; yield return f; x=arg[0];
Вызов самой функции превращается в y=RRFunc.Execute(f,x); RRFunc.Fact - преобразованная функция факториала: int fact(int k){ if(k>2) k*=fact(k-1); return k; }
public delegate IEnumerable<RFunc> RFunc(object[] argres);
class RRFunc {
public static object Execute(RFunc func,object obj) {
object[] arg=new object[1] { obj };
Stack<IEnumerator<RFunc>> stack=new Stack<IEnumerator<RFunc>>();
for(;;) {
if(func!=null) stack.Push(func(arg).GetEnumerator()); // recursive call
else if(stack.Count==1) return arg[0];
else stack.Pop();
stack.Peek().MoveNext();
func=stack.Peek().Current;
}
}
public static IEnumerable<RFunc> Fact(object[] arg) {
int k=(int)arg[0];
if(k>2) {
arg[0]=k-1;
yield return Fact;
arg[0]=(int)arg[0]*k;
}
yield return null;
}
}