[英]Is continuation style implementation of factorial tail call optimized (TCO)?
Here are two factorial implementation from this site : 这是此站点的两个析因实现:
Tail Call Optimized (TCO): 尾叫优化(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) ;
}
And the one rewritten in continuation style programming (callback): 然后用连续样式编程(回调)重写了一个:
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) ;
}
It seems that the tutorial suggest that the second is also TCO, but the last thing the second version returns is undefined
and its call is not in tail position according to this tutorial . 看来该教程建议第二个也是TCO,但是根据本教程 ,第二个版本返回的最后一个内容是undefined
并且其调用不在尾部。
However it also seems that return
is not used at all here and hence there is no need to create a new frame on stack with the address to return to. 但是,这里似乎也根本没有使用return
,因此不需要在堆栈上创建带有返回地址的新帧。 So is this what makes the second implemenation TCO? 那么,这是什么使第二实现的总拥有成本呢?
Node7 with --harmony_tailcalls
doesn't consider the second one valid for TCO, but TCO isn't 100% complete in V8 (hence being behind a runtime flag). Node7与--harmony_tailcalls
不考虑TCO的第二个有效的,但是TCO是不是在V8 100%完成(因此暂时落后运行时标志)。
Axel Rauschmayer says no, it's not a tail call , because there's an implicit return undefined
; 阿克塞尔·劳斯迈耶( Axel Rauschmayer) 表示不,这不是尾注 ,因为存在一个return undefined
的隐式return undefined
; after it: 之后:
The function call
bar()
in the following code is not in tail position: 以下代码中的函数调用bar()
不在尾部位置:function foo() { bar(); // this is not a tail call in JS }
The reason is that the last action of
foo()
is not the function callbar()
, it is (implicitly) returningundefined
. 原因是foo()
的最后一个动作不是函数调用bar()
,它(隐式地)返回undefined
。 In other words,foo()
behaves like this: 换句话说,foo()
行为如下:function foo() { bar(); return undefined; }
Callers can rely on
foo()
always returningundefined
. 调用者可以依靠foo()
始终返回undefined
。 Ifbar()
were to return a result forfoo()
, due to tail call optimization, then that would change foo's behavior. 如果bar()
由于尾调用优化而返回foo()
的结果,那么这将改变foo的行为。
So in other words, at the end of foo
, we can't just jump to bar
, because bar
may issue a return
with a value other than undefined
, whereas foo
doesn't return any value at all (and thus calling it is guaranteed to yield undefined
). 因此,换句话说,在foo
的末尾,我们不能只跳到bar
,因为bar
可能会使用undefined
以外的值发出return
,而foo
根本不返回任何值(因此可以保证调用它产生undefined
)。 Something has to stay behind (at least for now) when we call bar
to say "but don't return bar
's return value." 当我们打电话给bar
说“但不要返回bar
的返回值”时,至少要留一些东西 (至少现在是这样)。 That something is a stack frame. 那是一个堆栈框架。
In theory , the JavaScript engine could pass some kind of flag when calling bar
telling itself to throw away any value bar
returns, thus allowing TCO in that case, but I don't see anything in the spec that does that. 从理论上讲 ,JavaScript引擎可以在调用bar
告诉自己放弃任何value bar
返回值时传递某种标志,从而在这种情况下允许TCO,但我在规范中看不到任何实现此目的的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.