Search code examples
erlangtail-recursion

Does using a lot of tail-recursion in Erlang slow it down?


I've been reading about Erlang lately and how tail-recursion is so heavily used, due to the difficulty of using iterative loops.

Doesn't this high use of recursion slow it down, what with all the function calls and the effect they have on the stack? Or does the tail recursion negate most of this?


Solution

  • Iterative tail recursion is generally implemented using Tail calls. This is basically a transformation of a recursive call to a simple loop.

    C# example:

    uint FactorialAccum(uint n, uint accum) {
        if(n < 2) return accum;
        return FactorialAccum(n - 1, n * accum);
    };
    uint Factorial(uint n) {
        return FactorialAccum(n, 1);
    };
    

    to

    uint FactorialAccum(uint n, uint accum) {
    start:
        if(n < 2) return accum;
        accum *= n;
        n -= 1;
    goto start;
    };
    uint Factorial(uint n) {
        return FactorialAccum(n, 1);
    };
    

    or even better:

    uint Factorial(uint n) {
        uint accum = 1;
    start:
        if(n < 2) return accum;
        accum *= n;
        n -= 1;
    goto start;
    };
    

    C# not real tail recursion, this is because the return value is modified, most compilers won't break this down into a loop:

    int Power(int number, uint power) {
        if(power == 0) return 1;
        if(power == 1) return number;
        return number * Power(number, --power);
    }
    

    to

    int Power(int number, uint power) {
        int result = number;
    start:
        if(power == 0) return 1;
        if(power == 1) return number;
        result *= number;
        power--;
    goto start;
    }