【问题标题】:What exactly is a pure function when we are talking about a function within a function当我们谈论函数中的函数时,究竟什么是纯函数
【发布时间】:2022-04-30 04:59:19
【问题描述】:

我了解到纯函数是一个不会改变全局状态的函数。如果这是真的,函数内的函数可以改变外部函数的状态,并且仍然是纯的,对吗?

例子:

function func1() {
  let name = "My Name"
  func2()  

  function func2() {
    // alter name here.
  }
}

在上面的例子中,func2 仍然是纯的,因为它不使用任何全局状态。

我是这么看的,但是我的工作同事认为func2 不纯,应该写成这样:

function func1() {
  let name = "My Name"
  func2(name)  

  function func2(name) {
    // use name here.
  }
}

这不好,因为:

  • 如果 v8 不对此进行优化,CPU 将运行更多指令
  • 阴影是一种不好的做法

问题是:当我们谈论函数中的函数时,纯函数到底是什么?

【问题讨论】:

  • 使用 != 改变。你说的是哪一个?
  • @Bergi 我想知道你对这两件事的看法。

标签: functional-programming purely-functional pure-function


【解决方案1】:

Purity 没有被定义为只关心全局变量,它关心任何不应该被改变的非本地 变量(以及更多)。闭包的外部变量仍然算作非局部变量,它不需要是全局变量。

所以如果func2 更改name,那么它就是不纯的。 func1 是否也会因此而变得不纯,这取决于您是否只考虑外部纯度——只要 namefunc2 在函数内保持本地,它可能仍然是纯的。

【讨论】:

    【解决方案2】:

    pure function 是一个满足 2 个要求的函数:

    1. 给定相同的输入,它总是会返回相同的输出。
    2. 不会产生副作用。

    Side effects 可以定义为'在被调用函数之外可观察到的任何应用程序状态变化,而不是其返回值'


    具体来说:

    • 修改其范围之外的任何内容(即使它不是全局范围)的函数不是纯函数。

    • 在您的示例中,如果 func2 在其自身范围之外修改变量,则它不是纯函数:

    function func1() {
      let name = "My Name"; // <-- the variable is not in the global scope but, in any case, it is outside the scope of func2
      func2();
    
      function func2() {
        // alter name here.
      }
    }
    

    【讨论】:

      【解决方案3】:

      我了解到纯函数是一个不会改变全局状态的函数。

      嗯,这太简单了。一个纯函数应该一,没有副作用,二,它的结果应该只依赖于参数。因此,作为推论,没有状态。您的func1name 属性可疑地看起来像一个状态。我可以变异它吗? func1() 会根据之前的调用产生不同的结果吗?不纯!

      当然,func2 不纯是无可争议的。您写了“更改名称”-“名称”超出了其范围。这是副作用。

      【讨论】:

        【解决方案4】:

        另一个我认为值得一提的例子是follow 纯函数

        function insert(DB, user) {
            return function() {
                throwIfUserExists(DB, user);
                var savedUser = saveUser(DB, user);
                return savedUser;
            }
        }
        

        请注意,当您调用insert 时,只要您继续发送相同的DBuser,您将收到与该函数返回另一个函数相同的输出 - 不会发生副作用。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-06-06
          • 1970-01-01
          • 1970-01-01
          • 2021-08-03
          • 2023-03-17
          • 2014-08-23
          • 2021-04-15
          • 2015-01-26
          相关资源
          最近更新 更多