It is difficult to pinpoint the trade-offs associated with recursion.
At a mathematically abstract level, recursion provides a powerful structure for describing the explicit behavior of a function. For example, we can mathematically define a factorial as
x! = 1 if x == 0 x! = x * (x - 1)! else
Or we could define a more complex function recursively, for example, how we could calculate "N choose K":
C(n, k) = 1 if k == 0 C(n, k) = 0 if k < 0 or if n > k C(n, k) = C(n - 1, k) + C(n - 1, k - 1) else
Using recursion as an implementation method does not guarantee that you will end up using more memory or code that works more efficiently. Often, recursion uses more space due to the memory required to store stack frames, but in some languages ββthis is not a problem, since the compiler may try to optimize function calls (see, for example, eliminating tail calls). In other cases, recursion can use huge resources until the recursive code cannot complete with simple problems.
Regarding performance issues, often recursive code is significantly less efficient than iterative code. Functional challenges are expensive, and a naive translation from recursion to code leads to unnecessary duplication of work. For example, a naive Fibonacci implementation
int Fibonacci(int n) { if (n <= 1) return n; return Fibonacci(n - 1) + Fibonacci(n - 2); }
It is wonderfully inefficient and so slow that it has never been used in practice. Although the code is cleaner, inefficiency takes away any potential benefits of recursion.
In other cases, recursion can be an amazing time saver. As an example, mergesort is a very fast sorting algorithm defined by beautiful recursion:
Mergesort(array, low, high) { if (low >= high - 1) return; Mergesort(array, low, low + (high - low) / 2); Mergesort(array, low + (high - low) / 2, high); Merge(array, low, low + (high - low) / 2, high); }
This code is very fast, and the corresponding iterative code is likely to be slower, harder to read, and harder to understand.
So, in short, recursion is neither a magic medicine, nor a force to be avoided. This helps to illuminate the structure of many problems that might otherwise seem difficult or almost impossible. Although it often leads to clearer code, it often does this at the expense of time and memory (although it is not necessarily automatically less efficient, in many cases it can be more efficient). It is definitely worth exploring to improve overall algorithmic thinking and problem-solving skills, even if you never write another recursive function in your life.
Hope this helps!