views:

425

answers:

5

I've been reading in a couple of places where people are opting to use a Stack instead of recursion. Is this because recursion is seen as being an outdated way to get-the-job-done or are both methods equally applicable in different contexts?

+8  A: 

No. Just the opposite. Recursion is the natural way to express a whole class of problems. A stack is a way to simulate that if you don't have recursion.

See, for example, this question. Or consider the sort of standard recursive function: computing the n-th Fibonacci number.

You'll recall that Fibonacci numbers are the series

0,1,1,2,3,5,8,13, ...

defined so that Fn = Fn-1+Fn-2.

This can be written as a recursive definition as

Base case:
F(0) = 0
F(1) = 1
Recursive step:
F(n) = F(n-1)+F(n-2)

So, you have F(0) = 0, F(1)= 1, F(2)=F(0)+F(1)=1, and so on.

A simple program to compute this (in C just for grins) is:

int fib(int n) {
    /* we'll ignore possible negative arguments, see Wikipedia */
    switch(n) {
       case 0: return 0; break;
       case 1: return 1; break;
       default: return fib(n-1)+fib(n-2); break;
    }
}

Notice how closely that program corresponds to the original definition?

The thing is, C manages all the intermediate results in the calling stack. Some languages aren't defined to do that (the only one I can think of offhand is old FORTRAN, but I'm sure there are others). If you are writing in assembler or old FORTRAN, then, you have to manage your own stack to keep track of those intermediate results.

Charlie Martin
I believe this answer is incorrect given the questions context
Mitch Wheat
I agree with you regarding recursion being the "natural way" to express problems (and upvoted you accordingly). However, I'd like to have seen some recognition that it is a bit more computationally expensive and so upvoted tpdi as well.
Mark Brittingham
Except that isn't true. Its more computatinoally expensive for some problems, and in some environments. This program, for example, is really expensive. On the other hand, with a little more work it could have been expressed as a tail recursion, as here: http://triton.towson.edu/~akayabas/COSC455_Spring2000/Recursion_Iteration.htm , and tail recursion is no worse than iteration and often better, see http://portal.acm.org/citation.cfm?id=800055.802039
Charlie Martin
+4  A: 

Updated to include fishlips' correction.

Using a Stack is a standard technique of eliminating recursion

See also: What is tail-recursion?

An example of Tail-Recursion (that can be removed using iteration):

public class TailTest
{   
    public static void Main()
    {    
        TailTest f = new TailTest();
        f.DoTail(0);
    }

    public void DoTail(int n)
    {    
        int v = n + 1;   
        System.Console.WriteLine(v);    

        DoTail(v);   // Tail-Recursive call
    }
}
Mitch Wheat
Every kind of recursion can be rewritten iteratively by utilizing stack structures. Recursion is a way to utilize the call stack to solve the problem.However, tail recursion can be rewritten using GOTOs, essentially transforming them to an iterative loop. That is the standard way of eliminating tail recursion.
fishlips
+7  A: 

Iteration is often faster/ has less overhead than recursion. With recursion, we implicitly use the machine's stack as our stack -- we get that "for free" -- but we pay the cost of expensive function calls (and attendant machine stack management).

But recursive functions are often more intuitive to write and to read.

Often, it's possible to write a function using recursion, leave that until it becomes a bottleneck, then replace it with an iterative function that uses an explicit stack.

tpdi
+1 - Good observation. As Charlie says, there are some problems that are just very natural for recursion. However, you do well to point out that developers need to know the trade-off they are making.
Mark Brittingham
Except it ain't necessarily so: this is an old wives tale. See Guy Steele's paper: http://portal.acm.org/citation.cfm?id=800055.802039
Charlie Martin
@Charlie Martin: It's probably safest to say: It depends, because it is impossible to predict what kind of implementation the compiler/interpreter has. I'm sure recursion is faster in Lisp, everything is recursion in Lisp, if it weren't faster, that would be a serious issue. As always, it depends, and if you really want to know what's faster, benchmark it.
altCognito
+3  A: 

If you are in a programming language/environment where tail calls grow the stack (no tail call optimization (TCO) applied), then it is best to avoid deep recursion, and iterative solutions that may use a stack data structure are preferred.

On the other hand, if you are in a language/environment that supports iterating with tail calls, or if the recursion depth will always be small, then recursion is often a fine/elegant solution.

(This is a little over-broad, but overall, I would by no means call recursion "out-dated".)

Brian
+1, I like that you noted how/why recursion can be faster.
altCognito
+2  A: 

No no, I think modern developers should emphasize readibility and ease of maintenance over some miliseconds.

If the problem IS recursive, I fully recommend your solution to BE recursive.

Besides, you may end up introducing some unespected bugs tryng to force an iterative/stacked solution.

Daniel Dolz
You got the nail on its head. You must choose the right tool depending on the task. But mostly readability matters over expressing a problem in a fixpoint.
sibidiba