views:

1148

answers:

13

As far as I know, most recursive functions can be rewritten using loops. Some maybe harder than others, but most of them can be rewritten. So the question is, under which conditions does it become impossible to rewrite a recursive function using a loop (if such conditions exist)?


Clarification: I know how to convert a recursive function to use a loop, but I am asking whether there are (corner) cases where this is impossible.

+3  A: 

They all can be written as an iterative loop (but some might still need a stack to keep previous state for later iterations).

Michael Burr
A: 

You can always use a loop, but you may have to create more data structure (e.g. simulate a stack).

Brian
+6  A: 

It's not so much a matter of that they can't be implemented using loops, it's the fact that the way the recursive algorithm works, it's much clearer and more concise (and in many cases mathematically provable) that a function is correct.

Many recursive functions can be written to be tail loop recursive, which can be optimised to a loop, but this is dependent on both the algorithm and the language used.

Spence
A: 

See also this SO question

Anonymous
A: 

Indirect recursion comes to mind...

Edit: Mile's answer shows how to inline indirect recursion, so I was wrong.

Hosam Aly
them maybe Miles deserves a +1 :)
Learning
He got it. :) I usually wait till responses are stabilised, so that I can assess different answers.
Hosam Aly
+2  A: 

I don't know about impossible but impractical->extremely inefficient examples are:

  • tree traversal (a bitch in any loop)

  • fast fourier

  • quicksorts (and some others iirc)

Basically anything where you have to start keeping track of boundless potential states

annakata
+9  A: 

Any recursive function can be made to iterate (into a loop) but you need to use a stack yourself to keep the state.

Normally, tail recursion is easy to convert into a loop:

A(x) {
  if x<0 return 0;
  return something(x) + A(x-1)
}

Can be translated into:

A(x) {
  temp = 0;
  for i in 0..x {
    temp = temp + something(i);
  }
  return temp;
}

Other kinds of recursion that can be translated into tail recursion are also easy to change. The other require more work.

The following:

treeSum(tree) {
  if tree=nil then 0
  else tree.value + treeSum(tree.left) + treeSum(tree.right);
}

Is not that easy to translate. You can remove one piece of the recursion, but the other one is not possible without a structure to hold the state.

treeSum(tree) {
  walk = tree;
  temp = 0;
  while walk != nil {
    temp = temp + walk.value + treeSum(walk.right);
    walk = walk.left;
  }
}
Gamecat
Your original tail-recursive example is not quite tail-recursive (but still illustrates the point that 'linear' recursion is often easy to translate, whereas higher arities are often not so easy).
Brian
Thanks. The last example seems to be what I am looking for. Is it really impossible to remove recursion from it?
Hosam Aly
No, you can always rewrite it with loops. It is almost mechanical to transform into code that uses continuations, which can be compiled into loops (not use the stack) in a language like F#, see e.g. http://lorgonblog.spaces.live.com/blog/cns!701679AD17B6D310!256.entry
Brian
Thank you. Your answer is very nice, but I chose Carl's answer because it's simpler (which is helpful to new readers of the thread).
Hosam Aly
A: 
1800 INFORMATION
Nice example. But a question remains: is it impossible, or just extremely difficult?
Hosam Aly
Not even too difficult if you know the general techniques.
Brian
I tried to do this, and it doesn't seem difficult to me. Check this code (and please tell me anything wrong with it): ...
Hosam Aly
push(m); push(n);while (stackSize > 1){ n = pop(); m = pop(); if (m == 0) push(n+1); else if (m > 0 push(1); } else if (m > 0 push(m); push(n-1); }}
Hosam Aly
Looks good to me
1800 INFORMATION
+13  A: 

When you use a function recursively, the compiler takes care of stack management for you, which is what makes recursion possible. Anything you can do recursively, you can do by managing a stack yourself (for indirect recursion, you just have to make sure your different functions share that stack). So no, there is nothing that can be done with recursion and that cannot be done with a loop and a stack.

Carl Seleborg
I have a related question: can all recursive functions be represented as a **single loop**?
abhin4v
+2  A: 

Indirect recursion is still possible to convert to a non-recursive loop; just start with one of the functions, and inline the calls to the others until you have a directly recursive function, which can then be translated to a loop that uses a stack structure.

Miles
+2  A: 

Every recursive function can be implemented with a single loop.

Just think what a processor does, it executes instructions in a single loop.

starblue
while(computer.on()) processNextInstruction();
Carson Myers
+1  A: 

In SICP, the authors challenge the reader to come up with a purely iterative method of implementing the 'counting change' problem (here's an example one from Project Euler).

But the strict answer to your question was already given - loops and stacks can implement any recursion.

Eli Bendersky
By "SICP", do you mean "Structure and Interpretation of Computer Programs" (http://mitpress.mit.edu/sicp/)?
Hosam Aly
@Hosam - yes, this name is an accepted acronym
Eli Bendersky
@eliben: This may be true for many people, but it's not the same for many others, especially new developers. If you use the acronym, I'd suggest making it a link.
Hosam Aly
A: 

Hi Hosam Aly,

Your stacking solution to the Ackermann problem is simply brilliant.

I am trying to solve the same for the Euler Project without any success.

Will now tinker with your idea/code.

Regards, nk

Nandakishore