尾递归优化:为什么'+'不允许这样做?

问题描述 投票:0回答:1

所以我看到的尾部递归的常见示例之一是:

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

已针对尾叫优化:

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

我明白了。但是我的问题是:为什么在这种情况下*不能在其上进行优化?我不能将顶部重写为

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

我知道这行不通。我认为这仅仅是因为这不是真正的尾递归调用?还是会优化尾巴吗?

javascript recursion tail-recursion
1个回答
2
投票

您的最后一个例子不是尾注,因为您必须继续呼叫factorial 之前,您可以呼叫multiply。考虑:

阶乘(5)在获得阶乘(4)的结果之前不能调用乘法在获得阶乘(3)的结果之前不能调用乘法在获得阶乘(2)的结果之前不能调用乘法在获得阶乘(1)的结果之前不能调用乘法在有阶乘(0)的结果之前不能调用乘法

仅在这一点上您停止递归并调用multiply。因此,没有尾声。

可能还值得注意的是,TCO几乎仅由Safari的JavaScriptCore实现。它不是由Chrome的V8或Firefox的SpiderMonkey实施的,也可能不是规范或没有规范。 :-)更多herehere

我应该注意,您要求的标题是

为什么'+'不允许呢?

确实。 TCO不在乎操作是什么*+,只是它位于尾部位置。

© www.soinside.com 2019 - 2024. All rights reserved.