【发布时间】:2020-06-18 11:53:04
【问题描述】:
在Pure function 上的维基百科文章中,有一个这样的不纯函数示例:
void f() {
static int x = 0;
++x;
}
加上“因为局部静态变量的突变”的说法。
我想知道为什么它不纯?它是从单位类型到单位类型的,因此对于相同的输入,它总是返回相同的结果。而且它没有副作用,因为尽管它有 static int 变量,但除此 f() 之外的任何其他函数都无法观察到它,因此其他函数可能使用的全局状态没有可观察到的突变。
如果有人认为不允许任何全局突变,无论它们是否可观察,那么现实生活中的任何函数都不能被认为是纯函数,因为任何函数都会在堆栈上分配其内存,而分配是不纯的,因为它涉及通过操作系统与 MMU 通信,分配的页面可能位于不同的物理页面中,等等。
那么,为什么这个无用的隔离 static int 会使函数不纯?
【问题讨论】:
-
例如:如果我没记错的话,经常调用
f会导致整数溢出和未定义的行为。 -
如果
x真的足够孤立,那么f可以被认为是纯粹的。但通常这意味着您实际上并不需要该变量。 -
我认为这个问题可以更好地表述为“为什么将这种不纯函数的退化情况视为不纯的情况有用?”因为我们不能反对所提供的定义(函数改变了一个局部静态变量。这就是定义。讨论结束)。
-
该示例被精简以仅突出这一方面:局部静态变量的突变。马虎地说“纯粹”的意思是,对于相同的输入,函数的作用完全相同
-
如果
x只是被操纵而从未被访问过,那么它是一个足够聪明的优化编译器消除的候选对象。这里的问题是“x是否会影响任何其他计算?”如果没有,则可以安全地删除x。如果可以删除,那么该功能可以制作纯功能,但需要删除该术语。
标签: c++ functional-programming category-theory