Tail Recursion optimization for JavaScript?

后端 未结 3 1225
生来不讨喜
生来不讨喜 2021-02-03 11:45

My apologies to everyone for previous versions of this being vague. Someone has decided to have pity on the new girl and help me rewrite this question - here\'s an update that

3条回答
  •  梦如初夏
    2021-02-03 12:01

    Many of the commonest languages lack tail-recursion optimisation, because they simply don't expect you to use recursion to solve linear problems.

    Tail-recursion optimisation only applies if a recursive call is the last thing your function does, meaning there's nothing that will need to look at the current stack content, and therefore no need to preserve it by adding another stack frame.

    Any such algorithm can be adapted into an iterative form. For example (psuedocode):

     int factorial(int x) {
          return factTail(x,1);
     }
    
     int factTail(int x, int accum) {
          if(x == 0) {
              return accum;
          } else {
              return(factTail (x-1, x * accum);
          }
     }
    

    ... is an implementation of factorial() that has been tailored to ensure that the last statement is to return the outcome of a recursive call. An engine which knew about TCO would optimise this.

    An iterative version that does things in the same order:

      int factorial(int x) {
          int accum = 1;
          for(int i=x; i>0; i--) {
              accum *= i;
          }
          return accum;
     }
    

    (I made it count backwards to approximate the execution order of the recursive version -- in practice you probably wouldn't do this for factorial)

    It's fine to use recursive calls if you know the recursion depth won't be huge (in this example, large values of x).

    Often recursion leads to very elegant specifications of a solution. Fiddling with the algorithm to get a tail-call detracts from that. See how the factorial above is harder to understand than the classic:

     int factorial(int x) {
         if(x == 1) {
             return 1;
         } else {
             return factorial(x-1) * x;
         }
     }
    

    ... yet this classic form is stack-hungry, for a task that shouldn't need a stack. So it could be argued that an iterative form is the clearest way to solve this particular problem.

    Due to the way programming is taught, most programmers today are more comfortable with the iterative forms than with recursive methods. Is there a particular recursive algorithm you're having specific trouble with?

提交回复
热议问题