以下 add()
功能是否参考透明?
const appState = {
runningTotal: 0
}
function add(x, y) {
const total = x + y;
appState.runningTotal += total;
return total;
}
由于我发现参考透明度的一些定义,我不确定答案 . 以下是我对其正确性的信心顺序 .
在以下情况下,函数是引用透明的:
-
它可以被其值替换,程序的行为保持不变
-
给定一些输入它将始终产生相同的输出
-
它只取决于它的输入
-
这是无国籍的
鉴于上述每个定义,我认为答案是:
-
也许 - 我认为这取决于appState.runningTotal如何在程序的其他地方使用,但我不确定 .
-
是的
-
我不确定 - 它只依赖于它的输入来产生输出,但它也在函数体中使用
appState
-
没有
回到具体问题:是 add()
引用透明?
提前致谢!
附: - 如果我把多个概念混为一谈,请告诉我,即 pure function
的概念 .
3 回答
不,它不是一个引用透明的功能 .
引用透明度特指您列出的第一个条件,即您可以在不改变程序行为的情况下自由替换表达式左侧和右侧的值 .
add(2,3)
返回值5
,但您无法在程序中用5
替换add(2,3)
的实例,因为add(2, 3)
也有5
递增runningTotal
的副作用 . 将add(2, 3)
替换为5
会导致runningTotal
没有递增,从而改变程序的行为 .我会去的
因为当它不被使用时,它可以被忽略 . 显然它是全局状态,但它只是用于调试还是它的实际应用程序状态的一部分?如果是后者,那么函数当然不是纯粹的 - 它确实改变了状态并用结果值替换了一个调用(或者做了不必要的调用,其结果被删除)会改变程序的行为 .
但是如果你确实认为
appState.runningTotal
不是程序语义的一部分,并且它的功能不依赖于它,你也可以忽略这个副作用 . 我们一直这样做,每个真实世界的计算都会影响它运行的计算机的状态,当我们考虑函数的纯度时,我们选择忽略它 .纯函数是引用透明的 . 我把它称为“copypastability”,也就是说你可以复制粘贴引用透明代码的每一部分,它仍然可以像最初的预期一样工作 .
必须满足所有这四个标准,尽管您可以将它们缩小到第一个语句 . 其他都可以从那个推断出来 .
如果可以合理地替换某个函数,则意味着您可以将其替换为具有输入作为键并输出为值的映射/字典 . 所以它总会在同一个输入上返回相同的东西 . 同样的类比与“仅依赖于输入”和“无状态”一样正常 .