2 回答
TA贡献1783条经验 获得超4个赞
这就是函数编程的思想。一切都是不可变的,不允许任何函数调用产生副作用。像您的示例一样,突变复杂对象的唯一方法是重新创建父对象。
现在的问题是如何更改程序状态。因此,我们首先考虑堆栈。它包含所有局部变量的值以及被调用函数的所有参数的值。我们可以通过调用新函数来创建新值。我们可以通过从函数返回来丢弃值。因此,我们可以通过调用函数来改变程序状态。但是,并非总是可以从函数中返回以丢弃其局部变量,因为我们可能只希望丢弃某些局部变量,而需要保留其他局部变量的值以进行进一步的操作。在这种情况下,我们根本无法返回,但是我们需要调用另一个函数并将仅一些局部变量传递给该函数。现在,为了防止堆栈溢出,功能语言具有称为“尾部调用优化”的功能,能够从调用堆栈中删除不必要的条目。如果关联函数唯一要做的就是返回自身调用的函数的值,则不需要调用堆栈。在这种情况下,没有必要保留调用堆栈条目。通过删除不必要的调用堆栈条目,将丢弃原本未使用的局部变量的值。您可能想了解一下在这里。另外,尾递归与此有关。
同样,这是纯函数式编程语言(如Haskell)的想法。一切都是不可变的,这真是太好了,但是这些语言只有它们自己的问题,并且有自己的处理方式。例如,Monad(以及更高种类的类型)可以在这些语言中使用,但是在命令式/面向对象的编程语言中很少见。
我喜欢在程序存储器的叶子处具有不变的值。但是,构成这些不可变值的代码实际上构成了应用程序逻辑,但确实包含可变状态。对我来说,这结合了两个世界的优势。但是,这似乎是一个优先事项。
添加回答
举报