函数式编程:状态与重新分配 [英] Functional programming: state vs. reassignment

查看:16
本文介绍了函数式编程:状态与重新分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要帮助弄清楚我当前的 OOP 状态概念与在 Haskell 或 Clojure 等函数式语言中实现的方式之间的差异.

I need help getting my head around the difference between my current OOP notion of state, and the way it would be done in a functional language like Haskell or Clojure.

举一个老生常谈的例子,假设我们正在处理简化的银行账户对象/结构/任何东西.在 OOP 语言中,我有一些类持有对 BankAccount 的引用,该类将具有诸如利率之类的实例变量,以及诸如 setInterestRate() 之类的方法,它们更改对象的状态并且通常不返回任何内容.在 Clojure 中,我有一个银行账户结构(一个美化的散列图),以及接受银行账户参数和其他信息并返回一个新结构的特殊函数.因此,我现在没有更改原始对象的状态,而是返回一个带有所需修改的新对象.

To use a hackneyed example, let's say we're dealing with simplified bank account objects/structs/whatever. In an OOP language, I'd have some class holding a reference to a BankAccount, which would have instance variables for things like interest rate, and methods like setInterestRate() which change the object's state and generally return nothing. In say Clojure, I'd have a bank-account struct (a glorified hashmap), and special functions that take a bank-account parameter and other info, and return a new struct. So instead of changing the state of the original object, I now have a new one being returned with the desired modifications.

那么……我该怎么办?覆盖引用旧银行帐户的任何变量?如果是这样,它是否比改变状态的 OOP 方法有优势?最后,在这两种情况下,似乎都有一个变量引用具有必要更改的对象.像我一样迟钝,我对正在发生的事情只有一个模糊的概念.

So... what do I do with it? Overwrite whatever variable was referencing the old bank-account? If so, does that have advantages over the state-changing OOP approach? In the end, in both cases it seems one has a variable that references the object with the necessary changes. Retarded as I am, I have only a vague concept of what's going on.

我希望这是有道理的,感谢您的帮助!

I hope that made sense, thanks for any help!

推荐答案

在纯函数式风格中,您永远不会覆盖任何变量.

In a pure functional style, you'll never overwrite any variable.

一个类比是物理学中的时空.如果您将世界视为 3d,则对象没有固定位置 - 它们会随着时间移动.为了将数学应用于物理世界,我们因此添加了一个时间维度并考虑了特定时间的各种属性的值.在这样做的过程中,我们已经将我们研究的对象变成了常量.类似地,在编程中,通过使用不可变值可以获得概念上的简单性.现实世界中具有身份的对象可以被建模为一系列不可变值(对象在增加时间时的状态),而不是单个变化的值.

An analogy would be to spacetime in physics. If you consider the world as 3d, then objects don't have fixed positions - they move over time. To bring math to bear on the physical world, we therefore add a time dimension and consider the values of various properties at particular times. In doing so, we've made the objects of our study into constants. Similarly, in programming, there is a conceptual simplicity to be had by working with immutable values. Objects with an identity in the real world can be modeled as a sequence of immutable values (the states of the object at increasing times) rather than as a single value that changes.

当然,如何将值序列与对象标识"相关联的细节可能有点麻烦.Haskell 有 Monads 可以让你模拟状态.Functional Reactive Programming 是一种更真实的尝试,通过纯函数更新对世界上的对象进行建模,我think 是一个非常有前途的编程方向.

Of course the details of how to associate the sequence of values to an "object identity" can be a little hairy. Haskell has Monads that let you model state. Functional Reactive Programming is a more literal attempt at modeling objects in the world with pure functional updates, that I think is a very promising direction for programming.

我会注意到 Clojure 与 Haskell 不同,它不是纯的,您可以按照您的建议更新变量.如果您只是在较高级别更新几个变量,您可能仍然会享受函数式编程在概念上的简单性好处.

I will note that Clojure, unlike Haskell, isn't pure, and you can update variables as you suggested. If you're only updating a few variables at a high level, you'll still probably enjoy many of the conceptual simplicity benefits of functional programming.

这篇关于函数式编程:状态与重新分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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