functional-programming

Loops by Recursive and Tail Recursive Functions

Introduction#

As you already know, for the sake of immutability you can’t process data using for loops and while loops. So we have recursive functions to rescue.

non-recursive (where immutability isn’t a concern)

function sum(numbers) {
    var total = 0;
    for (var i = numbers.length - 1; i >= 0; i--) {
        total += numbers[i];
    }
    return total;
}

It’s a procedural code with mutations (over total).

recursive to rescue

function sum(numbers) {
    if(numbers.length == 0) {
        return 0;
    }
    return numbers[0] + sum(numbers.slice(1));
}

this is the recursive version. there’s no mutation, but we are making a call stack as below which uses extra memory.

sum([10, 5, 6, 7]);

     10 + sum([5, 6, 7]);

          10 + 5 + sum([6, 7]);

               10 + 5 + 6 + sum([7]);

                    10 + 5 + 6 + 7 + sum([]);

                         10 + 5 + 6 + 7 + 0;

tail recursive to optimize

function sum(numbers) {
    return tail_sum(numbers, 0);
}

function tail_sum(numbers, acc) {
    if(numbers.length == 0) {
        return acc;
    }
    return tail_sum(numbers.slice(1), acc + numbers[0]);
}

in the tail recursive version, function return value does not need to wait till the end to do it its calculations, so there’s no huge stack here; only two levels.

sum([10, 5, 6, 7]);

     tail_sum([10, 5, 6, 7], 0);

     tail_sum([5, 6, 7], 10);

     tail_sum([6, 7], 15);

     tail_sum([7], 21);

     tail_sum([], 28);

     28;


This modified text is an extract of the original Stack Overflow Documentation created by the contributors and released under CC BY-SA 3.0 This website is not affiliated with Stack Overflow