函数式编程中的副作用是什么



我正在新学习Java 8,我看到一个与函数式编程相关的定义,即"仅使用纯函数创建的程序,不允许副作用"。

副作用之一是"就地修改数据结构"。

我不明白这一行,因为最后我们需要与数据库交谈以存储或检索或更新数据。

修改数据库不是函数式的意味着我们将如何在函数式编程中与数据库交谈?

"就地修改数据结构"意味着你直接操作输入数据结构(即列表)。"纯函数"是指

  • 结果只是它输入的函数,而不是其他隐藏状态
  • 该函数可以多次应用于同一输入,产生相同的结果。它不会更改输入。

在面向对象编程中,定义对象的行为。行为可以是提供对对象状态的读取访问权限、对对象的写入访问权限或两者兼而有之。当组合不同关注点的操作时,您可能会引入副作用。

例如,堆栈及其pop()操作。它将为每个调用生成不同的结果,因为它会更改堆栈的状态。

在函数式编程中,将函数应用于不可变值。函数表示数据流,而不是状态更改。所以函数本身是无状态的。函数的结果要么是原始输入,要么是与输入不同的值,但绝不是修改后的输入。

OO也知道函数,但这些函数并非在所有情况下都是纯粹的,例如排序:在非函数式编程中,您在原始数据结构("就地")中重新排列列表的元素。在 Java 中,这就是 Collections.sort()' 所做的。

在函数式编程中,您将对输入值(列表)应用排序函数,从而生成具有排序值的新值(新列表)。函数本身没有状态,并且不会修改输入的状态。

所以概括一下:给定相同的输入值,将函数应用于该值会产生相同的结果值

关于数据库操作。数据库本身的内容表示一种状态,它是其所有存储值、表等的组合("快照")。当然,您可以将函数应用于生成新数据的数据。通常,您将操作结果存储回数据库,从而更改整个系统的状态,但这并不意味着您更改函数的状态或输入数据。再次重新应用函数不会违反纯函数约束,因为您将数据应用于新的输入数据。但是将整个系统视为"数据结构"将违反约束,因为函数应用程序会更改"输入"的状态。

因此,整个数据库系统很难被认为是功能性的,但当然你可以以功能性的方式对数据进行操作。

但是Java允许你同时做(OO和FP),甚至混合两种范式,所以你可以选择最适合你需求的方法。

或者引用这个答案

如果你有几个需求混合在一起,混合你的范式。不要 限制自己只能使用您的右下角 工具箱。

最新更新