Observe a sequência aritmética a seguir e crie um programa para encontrar o valor do n-ésimo elemento:
Formulação recursiva
Observe com atenção o desdobramento da aplicação da formulação recursiva para o cálculo do quinto elemento da sequência.
Desdobramento
Veja que a cada chamada recursiva, forma-se uma sequência acumulada de operações cujo resultado final permanece em suspenso até a última aplicação da função. Esse acúmulo de valores exige espaço em memória da máquina e pode eventualmente causar problemas de estouro de memória.
Uma forma alternativa de lidar com esse comportamento e antecipar toda a computação parcial possível, reduzindo a necessidade de armazenamento da valores em memória, é acrescentar um parâmetro à função para agir como acumulador.
Formulação recursiva com acumulador
Desdobramento
Esse tipo de abordagem é conhecida como Recursividade na Cauda porque a chamada recursiva é a ÚLTIMA operação realizada! Atente para a diferença de comportamento da abordagem que não usa "cauda": a última operação realizada não é a chamada recursiva mas, sim, o somatório pendente .
Implementação em Javascript
const f = (n) => { return fAux(n,2) } const fAux = (n,acc) => { if (n == 1) {return acc} else return fAux(n-1,5+acc) }
Perceba que a implementação passa a considerar o nosso já conhecido uso de funcão de interface.
⚠️ CURIOSIDADE
Compiladores de muitas linguagens de programação (inclusive as tipicamente funcionais) conseguem otimizar bastante as operações e, assim, reduzir o tempo de execução dos programas recursivos quando detectam o uso de recursividade na cauda.
Em Javascript, porém, essa otimização não é tão garantida. Depende de versão do compilador, suporte do browser, etc. Não é objetivo da disciplina tratar de questões específicas a linguagens ou compiladores, mas apenas passar o conceito a ser aprendido. Quem tiver interesse em conhecer mais sobre essa otimização sugiro a busca na Internet pelo termo TAIL CALL OPTIMIZATION (TCO).