in lots of cases. End recursion is trivial. True begin recursion is nothing more difficult. In the general case, something like bar: foo; bar(something); baz; return anything;
it will heavily depend on the precise nature of something.
Basically all you have to do is to manually unroll the recursion and put this executing-the-same-code into appropriate loops. So first you iterate over all the foos (end recursion). Then you do the lowest-level special-case version of bar, then you do all the baz in reverse order, passing the return values on.
Now if you can predetermine the sequence of somethings, like in a factorial, you can easily unroll. If you have to calculate it in the foos, you might have to store it, i.e. build your own stack, queue or something. If you even need to calculate if (or when) bar is to be called at all, you're in trouble and cannot do it. And if foo or baz change some external state and look at it later on (thus building a hidden communication channel between the recursions), the program is crap anyway.
You can think about the recursion as the CPU iterating the same code over and over again, maintaining the local variables on its stack. When you try to code this as an iteration, you have to maintain the local variables yourself. |