In the book Functional Programming in Scala, in the context of explaining how recursion is often used in functional programming over imperative iteration, the authors show recursion via a factorial function using a helper function called "go" or "loop", and state that this is standard practice is functional scala programming:
...
def factorial(n: Int): Int = {
@tailrec def go(n: Int, acc: Int): Int = {
if (n <= 0 ) acc
else go(n - 1, n*acc)
}
go(n, 1)
}
...but one could just as easily, if not more concisely define it without a helper function thus:
...
def factorial(n: Int): Int = {
if (n <= 0) 1
else n * factorial(n - 1)
}
My understanding is that accumulating values and avoiding mutation is achieved in recursion by leveraging the stack frame and "passing" return values to the previous stack frame. Here, the authors appear to using an explicit accumulator parameter for a similar purpose.
Is there an advantage in using helper functions to accumulate values like this, or are they using this example to show how recursion relates to imperative iteration by explicitly passing state to the helper function?