简体   繁体   English

尾递归优化:为什么“+”不允许?

[英]Tail Recursion Optimization: Why does '+' not allow that?

So one of the common examples of tail recursion I see is:所以我看到的尾递归的常见例子之一是:

function factorial(x) {
    if (x <= 0) {
        return 1;
    } else {
        return x * factorial(x-1); // (A)
    }
}

An it's optimized for Tail call with:它针对尾调用进行了优化:

function factorial(n) {
    return facRec(n, 1);
}
function facRec(x, acc) {
    if (x <= 1) {
        return acc;
    } else {
        return facRec(x-1, x*acc); // (A)
    }
}

I get this.我明白了。 But my question is: Why isn't the * in this case a function that could be optimized on?但我的问题是:为什么在这种情况下*不是可以优化的函数? Couldn't I rewrite the top as我不能将顶部重写为

function factorial(x) {
    if (x <= 0) {
        return 1;
    } else {
        return multiply(x, factorial(x-1)); // (A)
    }
}

I know this won't work.我知道这行不通。 I think it's just because it's not a true tail recursive call?我认为这只是因为它不是真正的尾递归调用? Would this still be tail optimized though?不过,这仍然是尾部优化吗?

Your last example isn't a tail call because you have to keep calling factorial before you can call multiply .您的最后一个示例不是尾调用,因为您必须调用multiply之前继续调用factorial Consider:考虑:

factorial(5)
  can't call multiply until it has the result from factorial(4)
    can't call multiply until it has the result from factorial(3)
      can't call multiply until it has the result from factorial(2)
        can't call multiply until it has the result from factorial(1)
          can't call multiply until it has the result from factorial(0)

it's only at this point that you stop recursing and call multiply .只有在这一点上,您才停止递归并调用multiply So, no tail call.所以,没有尾声。

It's probably also worth noting that TCO is pretty much only implemented by Safari's JavaScriptCore.可能还值得注意的是,TCO 几乎仅由 Safari 的 JavaScriptCore 实现。 it isn't implemented by Chrome's V8 or Firefox's SpiderMonkey, nor is it likely to be, spec or no spec.它不是由 Chrome 的 V8 或 Firefox 的 SpiderMonkey 实现的,也不太可能是规范或没有规范。 :-) More here and here . :-) 更多这里这里

I should note that in your title you ask我应该注意到,在你的标题中你问

Why does '+' not allow that?为什么“+”不允许?

It does.确实如此。 TCO doesn't care what the operation is — * vs + — just that it be in the tail position. TCO 并不关心操作是什么—— * vs + ——只是它处于尾部位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM