整个程序可以不变吗? [英] Can a whole program be immutable?

查看:63
本文介绍了整个程序可以不变吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 我对不变性很熟悉,可以设计不变性类,但是我大部分都是学术知识,缺乏实践经验
  • 请参考上面的链接图像(尚未嵌入)
  • 从底向上看
  • 学生需要一个新地址
  • 我们创建了一个新学生,而不是真正地改变学生
  • mutator方法返回这个新对象

问题:如果假设mutator调用来自一个不可变的对象,那么如何处理这个新对象?

Question: What do do with this new object, presuming the mutator call came from an immutable object?

  • 新学生不能保存在讲座中,因为讲座也是不可变的
  • 所以我们还需要一个新的讲座,其中包括新的学生
  • 但是在哪里保存新的演讲?
  • 当然,在新学期中,它在哪里结束?
  • 至少可以通过使用组件外观模式来中断该链,该组件可以处理所有新对象的创建,而不必通过整个链转发呼叫.

问题:此操作在哪里停止?不必在某个地方至少有一个可变对象至少可以保存最顶层的实例吗?

Question: Where does this stop? Doesn't there have to be a mutable object somewhere to at least save the topmost instance?

推荐答案

这是函数式编程的思想.一切都是不可变的,不允许任何函数调用产生副作用.像您的示例一样,突变复杂对象的唯一方法是重新创建父对象.

This is the idea of functional programming. Everything is immutable, no function call is allowed to have side-effects. The only way to mutate complex objects, like in your example, is to re-create the parent objects.

现在的问题是如何更改程序状态.因此,我们首先考虑堆栈.它包含所有局部变量的值以及被调用函数的所有参数的值.我们可以通过调用新函数来创建新值.我们可以通过从函数返回来丢弃值.因此,我们可以通过调用函数来改变程序状态.但是,并非总是可以从函数中返回以丢弃其局部变量,因为我们可能只希望丢弃某些局部变量,而需要保留其他局部变量的值以进行进一步的操作.在这种情况下,我们根本无法返回,但是我们需要调用另一个函数并将仅一些局部变量传递给该函数.现在,为了防止堆栈溢出,功能语言具有称为尾调用优化的功能,该功能可以从调用堆栈中删除不必要的条目.如果关联函数唯一要做的就是返回自身调用的函数的值,则不需要调用堆栈.在这种情况下,没有必要保留调用堆栈条目.通过删除不必要的调用堆栈条目,将丢弃原本未使用的局部变量的值.您可能要在此处进行阅读.另外,尾递归与此相关.

Now the question is how to alter the program state. Therefore, we first think about the stack. It contains the values of all local variables as well as the value of all parameters to the called functions. We can create new values by calling new functions. We can discard values by returning from a function. Thus, we can mutate the program state by calling functions. However, it is not always possible to return from the function to discard its local variables, because we might want to only discard some of the local variables, but need to keep the value of others for further operations. In this case, we simply cannot return, but we need to call another function and pass only some of the local variables to it. Now, to prevent a stack overflow, functional languages have a feature which is called tail call optimization, which is able to remove unnecessary entries from the call stack. An entry of the call stack is unnecessary if the only thing that is left to do for the associated function is to return the value of the function that was called by itself. In this case, there is no point in keeping the call stack entry. By removing the unnecessary call stack entry, the values of the otherwise unused local variables is discarded. You might want to read about it here. Also, tail recursion is related to this.

同样,这是纯函数式编程语言的思想,例如 Haskell .一切都是不可变的,这真是太好了,但是这些语言只有它们自己的问题,并且有自己的处理方式.例如,Monad(以及更高种类的类型)可在这些语言中使用,但在命令式/面向对象的编程语言中很少见.

Again, this is the idea of purely functional programming languages like Haskell. It is really nice that everything is immutable, however these languages have their only issues and their own ways to handle these. For example, Monads (and therefore higher kinded types) are available in these languages, but are rarely seen in imperative/object oriented programming languages.

我喜欢在程序存储器的叶子处具有不变的值.但是,构成这些不可变值的代码实际上构成了应用程序逻辑,但确实包含可变状态.对我来说,这结合了两个世界的优势.但是,这似乎是一个优先事项.

I like to have immutable values at the leaves of my program memory. However, the code to compose these immutable values, which actually forms the application logic does contain mutable state. For me, this combines the advantages of both worlds. However, this seems to be a matter of preference.

这篇关于整个程序可以不变吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆