Recursion
Recursion is a function invoking itself with new arguments:
fun sumRec(i: Int, numbers: List<Int>): Long { return if (i == numbers.size) { 0 } else { numbers[i] + sumRec(i + 1, numbers) } }
We usually avoid recursion, due to Stack Overflow error that we may receive if our call stack is too deep. You can call this function with a list that contains a million numbers to experience it:
val numbers = List(1_000_000) {it} println(sumRec(0, numbers)) // Crashed pretty soon, around 7K
One of the great benefits of tail recursion is that it avoids the dreaded stack overflow exception.
Let's rewrite our recursive function using a new keyword, tailrec
, to avoid that problem:
tailrecfun sumRec(i: Int, sum: Long, numbers: List<Int>): Long {
return if (i == numbers.size) {
return sum
} else {
sumRec(i+1, numbers[i] + sum, numbers)
}
}
Now the compiler will optimize our call and avoid exception completely.