javascript - 当您真正想要产生副作用时, "functional programming"背后的哲学是什么?

标签 javascript functional-programming

我知道纯函数属于“函数式编程”范式,您创建一个没有任何副作用的函数,并且对于输入它总是返回相同的输出,例如:

function (a,b) {
    return a + b;
}

这是一个纯函数,因为对于输入我总是返回相同的输出并且我没有产生任何副作用。好的,我明白了。

但是当我真正想要创建一个副作用时,我如何才能制作“纯函数”,我如何才能留在“函数式编程”范例中,例如更改 DOM 中的文本内容,例如:

function changeContent () {
   let content = document.querySelector("#content");
   content.textContent = 'Hello World';
}

这个函数有副作用,它不是获取输入并返回输出,而是产生副作用,但这实际上是函数的重点。这还是“函数式编程”吗?在那种情况下如何保持“函数式编程”范式?

最佳答案

How can I stay in the "functional programming" paradigm when I actually want to create a side effect?

你真的不能。纯函数不得有任何副作用。

当然,这意味着我们实际上无法将执行任何操作的程序建模为纯函数。有两种解决方法:

  • 牺牲纯洁。只需编写一个具有副作用的函数即可。彻底记录下来,以便每个使用该功能的人都知道这一点。对程序的命令部分进行不同的推理。

    这是大多数编程语言的首选解决方案,因为它们不强制要求纯度,而且您经常可以摆脱它。

  • 构建一个(纯)数据结构,明确描述您希望程序具有的效果。然后有一个不纯的“解释器”来执​​行它们来“运行”你的程序。 (我不会在这里详细介绍这种数据结构如何工作,有不同的方法,解释会超出问题的范围)。

    在 Haskell 中,它强制所有函数的纯度,这个数据结构是 IO 类型,它基本上描述了命令式计算,并且它的解释器内置在运行时中。
    在同样保证纯度的 Elm 中,有 Elm architecture在浏览器中使用 Web API 和 DOM 进行建模,并且在编译为 JS 时每个程序都需要一个小的运行时。

在 JavaScript 中,没有这样的解释器。您可以自己构建一个(或使用为此目的构建的库),但最终您必须在程序中的某处调用它的 run 函数,这会将您带回到#1。

特别是对于 DOM:描述文档更改的数据结构相对容易构建。您甚至可以引入纯功能优化,例如将避免多次写入同一位置,或写入随后无论如何都会被删除的位置。

但是,DOM 是 JavaScript 异步特性的基础部分。很难描述与多事件输入和输出的潜在并发交互。

关于javascript - 当您真正想要产生副作用时, "functional programming"背后的哲学是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50568722/

相关文章:

javascript - 每 10 次访问显示一次 JavaScript 函数(重新加载)

javascript - jquery自动完成id和值

haskell - Monad 不就是一个语法糖吗?

c++ - 这里如何正确使用for_each?

javascript - $(this).index() 和 element.index(this) 之间的区别

javascript - 在一个 img 标签中一个接一个地加载两个图像

javascript - 为什么 .replace 方法使用正斜杠字符来括起第一个参数?

javascript - Ramda : How to change only one value of an object, 基于对象的其他值

clojure - 为什么 Clojure 的 core.reducers 比惰性集合函数更快

Kotlin 如何将 JSONArray 映射到类型(流)