function sum(n) {
if (n == 0) {
return 0
} else {
return n + sum(n - 1)
}
}
console.log(sum(10000))
Da stack overflow no JS. Ex:
sum(5)
5 + sum(4)
5 + (4 + sum(3))
5 + (4 + (3 + sum(2)))
5 + (4 + (3 + (2 + sum(1))))
5 + (4 + (3 + (2 + 1)))
15
Se mudar pra:
function tailrecsum(n, result) {
if (n == 0) {
return result
} else {
return tailrecsum(n - 1, n + result)
}
}
A recursão vem logo depois do "return". Isso é chamado de tail recursive
.
Ex:
tailrecsum(5, 0)
tailrecsum(4, 5)
tailrecsum(3, 9)
tailrecsum(2, 12)
tailrecsum(1, 14)
tailrecsum(0, 15)
15
o que permite o JS transformar em um loop:
function sum(n, result) {
var args = [n, result];
while (true) {
var [n, result] = args
if (n == 0) {
return result
} else {
args = [n - 1, n + result]
}
}
}
console.log(sum(1000000, 0))
O Formality consegue fazer esse "estilo de loop", mas a função tem que ser tail recursiva pra isso. Então sempre que tiver um overflow, é uma questão de mudar o estilo da função.