是阶乘尾调优化(TCO)的延续式实现吗?

时间:2017-04-10 08:08:14

标签: javascript tail-call-optimization

以下是两个因子实现from this site

尾调优化(TCO):

function fact(n) {
  return tail_fact(n,1) ;
}

function tail_fact(n,a) {
  if (n == 0)
    return a ;
  else
    return tail_fact(n-1,n*a) ;
}

在延续式编程(回调)中重写的那个:

function fact(n,ret) {
  tail_fact(n,1,ret) ;
} 

function tail_fact(n,a,ret) {
  if (n == 0)
    ret(a) ;
  else
    tail_fact(n-1,n*a,ret) ;
}

似乎教程建议第二个版本也是TCO,但第二个版本返回的最后一个是undefined,并且根据this tutorial,它的调用不在尾部位置。

然而,似乎这里根本没有使用return,因此不需要在堆栈上创建一个带有要返回的地址的新帧。这是第二次实施TCO的原因吗?

1 个答案:

答案 0 :(得分:2)

带有--harmony_tailcalls的Node7并不认为第二个对TCO有效,但TCO在V8中没有100%完成(因此落后于运行时标志)。

Axel Rauschmayer says no, it's not a tail call,因为隐含return undefined;在它之后:

  

以下代码中的函数调用bar()不在尾部位置:

function foo() {
    bar(); // this is not a tail call in JS
}
     

原因是foo()的最后一个操作不是函数调用bar(),而是(隐式)返回undefined。换句话说,foo()的行为如下:

function foo() {
    bar();
    return undefined;
}
     

来电者可以依赖foo()始终返回undefined。如果bar()要返回foo()的结果,由于尾调用优化,则会改变foo的行为。

换句话说,在foo的末尾,我们无法跳转到bar,因为bar可能会发出return的值undefined除了foo之外,undefined根本不会返回任何值(因此调用它会保证产生bar)。当我们致电bar说'#34}但不要返回bar时,某事必须留下(至少现在) 。值#&34;那东西是堆栈框架。

理论上,JavaScript引擎可以在调用bar时传递某种标志,告诉自己丢弃任何值 <div id="googlemaps"></div> <div id="contactform"> <form> <div class="row"> <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12"> <div class="form-group"> <input type="text" class="form-control input-lg" id="firstname" placeholder="First Name"> </div> </div> <div class="col-lg-6 col-md-6 col-sm-12 col-xs-12"> <div class="form-group"> <input type="text" class="form-control input-lg" id="lastname" placeholder="Last Name"> </div> </div> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"> <div class="form-group"> <input type="text" class="form-control input-lg" id="email" placeholder="Email"> </div> </div> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"> <div class="form-group"> <textarea class="form-control" rows="3" placeholder="Message"></textarea> </div> </div> <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12"> <button type="submit" class="btn btn-default btn-lg btn-block">SEND MESSAGE</button> </div> </div> </form> </div> 返回,从而在这种情况下允许TCO,但我没有看到规范中的任何内容。