Interesting. Why is recursion bad? After all, this is the same cycle, even more so, with the ability to transfer parameters. Such a "loop" can be stopped by return . And it happens that without it in any way (Fibonacci numbers).

Why in real projects avoid its use?

  • excuse me, “no way without it” - is it without recursion to calculate the fibonacci numbers? - pavel
  • Well, this is just an example, most likely there are still other "beztotogonikak" - Flippy
  • one
    The Fibonacci sequence is perfectly computed without recursion. - D-side
  • 2
    Well, you know, there is nothing in the world that can be unambiguously described as "bad" or "good", so the question is initially incorrect. In the right place, with straight arms ... - user207618

4 answers 4

None of the means of language can be bad or good by definition.

Recursion allows a programmer to express his thoughts more clearly to everyone (and first of all to the compiler), but the price for this is an understanding of what is happening. You need to understand what a stack is, how it works, what is put on the stack when you call it. You need to have a slightly more developed imagination in order to understand when the recursion stops and what will happen to it during calls. You need to understand why global variables need to be changed carefully and, at the same time, why there should be as few variables as possible in the function (up to reuse).

However, any recursive algorithm can be written without recursion. (Usually using a dynamically expanding array)

The main problems specifically recursion - the inability to use it. Many programmers, looking at the code from https://ru.stackoverflow.com/a/39232/182935, will say that it is correct. In fact - there is a gross error hidden - an exponential rather than a linear increase in the number of operations and memory (well, if you write not on a functional PL).

Also from the classic recursion - the inability to properly set the stack using compilation keys (how often in Java you collected from the command line, for example, or maybe you remember how to start a thread with a large stack).

Therefore, a resume (sorry for being rude), if you ask this question, then do not use recursion, if you realize what you are doing - then this is a very handy tool that improves the readability of the code in a number of tasks and allows the compiler to work and not you in the sense of optimizations.

  • I now wanted to know what the gravest error was in the answer in the link: D - Alexey Shimansky
  • 2
    I will assume that, when passing a number less than 1 to the parameter, the recursion will never end. - Kirill Malyshev
  • @ Kirill Malyshev is not the worst thing, it’s just a bug. But if you pass the number 30 =) - pavel
  • Great answer, thanks :) - Flippy
  • экспоненциальный а не линейный рост - why linear? Fibonacci is perfectly calculated for O(log(n)) - vp_arth

Recursion is not bad. It just requires careful attention to the stack. As it grows with each step, which often leads to overflow.

And in principle, it can be replaced by an iteration (loop). What is usually advised to do in languages ​​where there is no tail recursion .

For example, in scala, you can explicitly indicate that the tail recursion should be used with the @tailrec annotation, then the call will be replaced with a transition (go to).

  • Aaaaaaa, that's it. The stack stores the calls to the methods. And how does the stack behave in recursion? He must transfer control to complete the method to whoever called it. What happens to the stack at this moment? - Flippy
  • For Java, recursion is just a method call. What happens when the method is called? Roughly speaking, the entire context of the method is saved to the stack. - Mikhail Vaysman
  • No, no, I'm talking about the fact that when a method is working, then control passes to the one who called it, that is, the same method. And in the end, the stack does not "kill" them? - Flippy
  • one
    this is called context. - Mikhail Vaysman

Incorrect use of recursion can lead to stack overflow and huge computational overhead. However, the recursive approach has a significant advantage in the naturalness of the algorithm: when using the apparatus of mathematical induction, you can easily test the correctness of the result (bearing in mind the features of data representation in memory). I recommend to mark recursive procedures with the @tailrec annotation to check the optimization of the function.

To optimize the recursive method, they usually resort to tail recursion: an additional parameter is passed to the function that stores the results of the previous calculation. However, in some cases this is not enough: for example, in the same example with Fibonacci numbers: here you need to store a list of results. For this you can use lazy collections, inside or outside the method. Sometimes there are more complex tasks when, for example, you need to find the best list of results. In this case, you can use recursion with clipping elements.

    Resource cost. While the program goes deep into recursion, memory space is allocated for local variables. And in the loop, the variables are simply updated.

    • Even worse :) Ie, if local variables are declared in the method, 20 pieces, then if the recursion is called 200 times, then they will already be diesters - Flippy
    • And there is already close to ekzepshna. - Flippy
    • NotSouchOfMemoryException - Flippy
    • one
      if you have 2,000 variables out of memory, then you are doing something completely different ... - pavel