-4

Preface

I had read a lot on why to prefer recursion over iteration, but I still have not seen any question that explain when to prefer iteration over recursion.

Motivation

Certainly, I believe there is no best tools to solve everything.

For example, both spoon and fork are eating tools, but spoon is more suited for eating rice while fork is more suitable for eating noodles.

Obviously, I will be a fanatic if I say that fork(or spoon) is the best tool for eating.

So, it is the same as recursion or iteration, both of them are tools, they each have their own benefits and disadvantages.

However, after searching through Googles and StackOverflow, although I found a lot of example on why recursion is more readable than iteration, but I still had not found any example on when iteration is more readble than recursion.

Thus, I seek to find out situations where iteration will be more readble. Just like how the ancient human realize fork is better than spoon at handling noodles.

Expected answer

Therefore, I hope to get answers that meet the following requirement:

  1. Explain a situation on when will iteration be more readable than recursion
  2. Give an example of algorithm (such as Bubblesort etc.) in pseudocode to demonstrate that iteration is more readable than recursion in such case

Note

  • Please note that I don't care about performance, what I care is the code readability.
  • Therefore, you can use any imperative language, but not Haskell (or its derivatives) as they don't support loops.

Reference

Wong Jia Hau
  • 2,639
  • 2
  • 18
  • 30
  • Is there a specific language that you are focusing on? Different languages may have different optimizations for one or the other. – Andrew Fan Jun 06 '18 at 03:57
  • Actually I'm not concerning about which language, rather I want an explanation on a theoretical level. – Wong Jia Hau Jun 06 '18 at 03:58
  • Someone needs to give the final vote to close this question. – Enigmativity Jun 06 '18 at 05:39
  • @Enigmativity May I know why this question deserved to be closed? – Wong Jia Hau Jun 06 '18 at 05:40
  • "Many good questions generate some degree of opinion based on expert experience, but answers to this question will tend to be almost entirely based on opinions, rather than facts, references, or specific expertise." – Enigmativity Jun 06 '18 at 05:41
  • Ok, then please tell me why the same question like this [Why should recursion be preferred over iteration?](https://stackoverflow.com/questions/2185532/why-should-recursion-be-preferred-over-iteration) does not get closed? This question also conforms to the criteria you mentioned. I don't really understand, I just flip the question around then it deserves to be downvoted and closed? It's like "Why men should cook?" will get upvoted by feminist but "Why women should cook?" will be downvoted by them. May I ask is this some kind of bias? – Wong Jia Hau Jun 06 '18 at 05:42
  • 3
    @WongJiaHau - You're right. It should have been closed. I have voted on that one too. – Enigmativity Jun 06 '18 at 05:56
  • @Enigmativity The other question, unlike this one, at the very least, in the first sentence is asking: _"Iteration is more performant than recursion, right?"_ Performance is something that can be objectively measured. Elegance and readability, on the other hand, how do we measure them? At OP: Your question is specifically asking for opinion based answers. There is no theory (see _"I want an explanation on a theoretical level"_) about elegance of iterations vs recursion. You are asking about "theory" only to make this question _sound_ more "objective". – AGN Gazer Jun 06 '18 at 11:19
  • 1
    What I mean by saying that your question is "opinion-based" is that no one has performed any measurements on how elegant is recursion vs iterations. For example, I am not aware of any fMRI studies that would measure what regions of the brain (e.g., pleasure centers) are excited when looking at recursive code vs iterative code. I also do not think there are studies that would measure levels of dopamine released when looking at the two ways of coding. Without this, no one can answer _objectively_ your question. Just use what _you_ like more or feel more comfortable with. – AGN Gazer Jun 06 '18 at 11:55
  • @WongJiaHau, I have some recent answers that talk about this: [functional programs vs functional programming](https://stackoverflow.com/a/49474143/633183) and [deepFind: imperative vs functional](https://stackoverflow.com/a/50456572/633183) and [combinations: imperative vs functional](https://stackoverflow.com/a/49563754/633183) – the Q&A's explore several implementations of the same program and detail the many trade-offs in each. I typically favor functional style, but depending on the algorithm, sometimes imperative style reads better; especially in the case of generators! – Mulan Jun 06 '18 at 20:16
  • @JaredSmith Perhaps you came from an engineering background, because the purpose of this question is due to research purpose. Because again, your statement can be applied to any Haskell researcher who cares about theoretical elegantness rather than conversion rate. – Wong Jia Hau Jun 07 '18 at 01:07
  • @AGNGazer Yes I understood that this is quite an opinion-based question, perhaps I came to the wrong StackExchange site, so do you have any suggestion that which StackExchange is more suitable for this type of question? – Wong Jia Hau Jun 07 '18 at 01:15
  • @WongJiaHau *readability* is usually mentioned in an engineering context. If you were aiming for *elegance* it may have been better to phrase it that way. – Jared Smith Jun 07 '18 at 02:04
  • @JaredSmith At first I used the term **elegance** (you can check my edit history) but then they said it was too broad, then I changed to **readability**, then they said it was too opinion-based. Mate, just which term should I use? – Wong Jia Hau Jun 07 '18 at 03:00
  • 1
    @WongJiaHau lol I didn't realize and I'm sorry. To be fair, I'm not sure this is answerable in the space of a stack overflow answer. I'm not sure it's answerable at all. Elegance is probably closer to what you want though than readability. Readability is context-dependent: `[].slice.call(arguments)` is familiar to every JavaScript developer working in industry but is rather opaque to others. Whereas I think we have a higher degree of general agreement when we say something is *elegant*: e.g. Euler's identity is elegant, the quicksort algorithm is elegant, etc. – Jared Smith Jun 07 '18 at 12:58

2 Answers2

2

To avoid an opinon-based answer I'd like to expand on the meaning of recursion:

When talking about recursion, it is important to distinguish between functions that are recursively defined, and functions that generate a recursive process.

Of the two aspects the latter is by far more important (assuming that you are writing a program to solve an actual problem). Given the choice between an iterative process and a recursive one, the former is the better, regardless of readability or elegance, as the difference in efficiency is enormous.

As an example, consider computing fibonacci numbers, and let's do it in Haskell, to show that this is not about loops vs function calls:

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n-1) + fib (n-2)

This generates a recursive process, for instance fib(4)

                   fib(4)
                    |
          ----------+----------
         fib(3)              fib(2)  
           |                   |
      -----+----          -----+---- 
    fib(2)    fib(1)   fib(1)     fib(0)
       |          |      |          |
       |          1      1          0
  -----+----  
fib(1)   fib(0)
 |        |
 1        0

Compare this to an iterative process (generated by a recursively defined function):

fibIter :: Int -> Int
fibIter n = iter 1 0 n
    where
    iter :: Int -> Int -> Int -> Int
    iter _ b 0 = b
    iter a b m = iter (a+b) a (m-1)

Where the process generated by fib(4) is

fibIter 4
iter 1 0 4
iter 1 1 3
iter 2 1 2
iter 3 2 1
iter 5 3 0
3

Note that the recursive process generates an exponential number of function invocations, where the iterative process does a linear number of function invocations (and only needs constant space if tail calls are eliminated).

In other cases, and in languages that do tail call elimination and have loop constructs, I'd say that the choice between writing a loop or using recursion is a matter of taste or programming conventions (making this opinion based).

Update about the readability of the bubblesort implementations:

It can be argued that the recursive formulation is more clear as it directly expresses the algorithm as

  1. Bubble up the largest element and put this last in the result
  2. Sort the rest of the elements with bubblesort

which -- again, arguably -- requires less mental housekeeping than the iterative formulation with loops and local variables.

For clarity, I would probably write the recursive bubblesort something like

bubbleSort :: Ord a =>  [a] -> [a]
bubbleSort [] = []
bubbleSort l = bubbleSort rest ++ [largest]
    where tmp = bubbleUpLargest l
          largest = last tmp
          rest = init tmp
          bubbleUpLargest (x:y:xs)
            | x > y = y:bubbleUpLargest (x:xs)
            | otherwise = x:bubbleUpLargest (y:xs)
          bubbleUpLargest x = x
drRobertz
  • 3,490
  • 1
  • 12
  • 23
  • Thanks for kindly answering my question. Actually, I came out with this question is because I found out that the recursive version of bubblesort is actually much less clearer than the iterative version. (Compare [Bubblesort in Haskell](https://gist.github.com/zooxyt/fbeb790f6c95fc0f78c1536a9af2beb2) with [Bubblesort in Javascript](https://stackoverflow.com/questions/7502489/bubble-sort-algorithm-javascript)). Thus I'm wondering if there are more examples regarding this matter. – Wong Jia Hau Jun 06 '18 at 06:34
  • @WongJiaHau I added a comment on the bubblesort example – drRobertz Jun 06 '18 at 10:38
0

Iteration-based code is - in most cases - less memory-intensive. Perhaps the best answer to this question lies in how recursion works.

When the program redirects to the "start" of a function using recursion, the C++ language does not re-use the existing instance of the function. Instead, a new instance of the function is created and the program counter is moved to the start of the new instance. The address of the old instance is placed on the Stack Buffer awaiting the return of the new instance.

However, when using iteration, the program counter is moved to the start of the existing instance of the code. No stack necessary.

This is the reason that iteration is strongly favored in many low-level programming applications that use C/C++. When programming Micro-controllers, you would almost never want to use recursion, because the stack buffer would only be able to hold a very small number of function addresses.

However, there are some occasions where recursion just makes sense. In the field of Signal Processing, the mathematics often breaks down into formulas that require recursion, and you cannot always find a closed-form version of the equation. In cases such as this, when running on a computer with sufficient memory, recursion can be the best option.

Furthermore, recursion is extremely useful in navigating File Trees. Consider the following code Code Example. Notice specifically the simplicity of his void DFS(struct node *head) function.

The truth is, with sufficient memory, recursion can be very useful. So it's not really a competition between recursion and iteration, but rather understanding the limitations that each method has.

armitus
  • 712
  • 5
  • 20
  • Thank you for taking your time to answer my question, but I think you may be misunderstanding my question. First of all, I understand the concept of recursion, and I understand that you need to keep a custom stack if you use iteration for some algorithm such as Fibonacci Sequence. Secondly, I certainly understand iteration will have better performance than recursion (although not all the time), but as I had mention, I do not care about performance, what I care is **code elegantness**. – Wong Jia Hau Jun 06 '18 at 04:53
  • @WongJiaHau _"code elegantness"_ is opinion-based. Do you want others to decide what you should like? – AGN Gazer Jun 06 '18 at 05:01
  • How does this answer the question?? – Enigmativity Jun 06 '18 at 05:19
  • @AGNGazer Perhaps I used the wrong term, what I mean is **readability**. – Wong Jia Hau Jun 06 '18 at 05:24
  • @WongJiaHau - **readability** is worse. Readable by what/whom? The Compiler has no trouble with either. Humans fall into two camps - those who can read recursion and those who can't. – Enigmativity Jun 06 '18 at 05:38
  • @Enigmativity Anyway, may I express my dissappointment? I tried to formulate my question as detailed as possible already, but what I feel from you guys (the moderators) is that you are just trying to find the flaw in the question instead of really trying to understand the question. Is StackOverflow a place to find flaws in question or is it a place to ask question? – Wong Jia Hau Jun 06 '18 at 05:55
  • 2
    @WongJiaHau - The community's role is to try to improve the quality of all questions and answers on SO. That might mean exposing flaws, but it is about creating clear and definitive answers to specific problems. Questions that are primarily opinion based don't fall in to that space. – Enigmativity Jun 06 '18 at 05:59