40

纯函数是没有副作用的函数——它不能做任何类型的 I/O,也不能修改任何东西的状态——而且它是引用透明的——当使用相同的输入多次调用时,它总是给出相同的输出。

为什么用“纯”这个词来描述具有这些属性的函数?谁首先以这种方式使用“纯”这个词,什么时候?有没有其他意思大致相同的词?

4

5 回答 5

24

为了回答您的第一个问题,就某些特定变量而言,数学函数通常被描述为“纯”。例如:

第一项是x的纯函数,第二项是y的纯函数

因此,我认为您不会找到真正的“第一次”出现。

对于编程语言,稍作搜索表明Ada 95 ( pragma Pure)、High Performance Fortran (1993) ( PURE) 和VHDL-93 ( pure) 都包含“纯函数”的正式概念。

Haskell (1990) 相当明显,但纯度并不明确。GCC 的 C 具有用于各种不同级别的“纯”的各种功能属性。

几本书:Rationale for the C programming language (1990) 使用了这个术语,Programming Languages and their Definitions (1984) 也是如此。但是,两者显然都只使用一次!为 IBM 个人计算机编程,Pascal(也是 1984 年)使用了这个术语,但从 Google 的受限观点来看,Pascal 编译器是否支持它并不清楚。(我怀疑不是。)

有趣的是,Ada 的前身 Green实际上有一个相当严格的“函数”定义——甚至不允许内存分配。然而,这在成为 Ada 之前就被删除了,其中函数可以有副作用(I/O 或全局变量),但不能修改它们的参数。

C28-6571-3(第一本 PL/I 参考手册,在编译器之前编写)表明 PL/I 早REDUCIBLE在 1966 年就以 (= pure) 属性的形式支持纯函数 - 当编译器首次发布。(这也回答了你的第三个问题。)

最后一份文档特别指出,它包含REDUCIBLE自文档 C28-6571-2 以来的新更改。所以REDUCIBLE,这可能是编程语言中形式化纯函数的第一个化身,出现在 1966 年 1 月到 7 月之间。

更新:从这个意义上说,Google Groups 上“纯功能”的最早实例是从 1988 年开始的,这很容易比书籍参考文献晚。

于 2011-10-13T09:02:37.223 回答
15

A couple of myths:

  • The term "pure functional" doesn't come from mathematics, where all functions are by nature "pure" and, so, there was never any need to call anything a "pure function".

  • The term doesn't come from imperative programming. The early imperative programming languages, Fortran, Algol 60, Pascal etc., always had two kinds of abstractions: "functions" that produced results based on their inputs and "procedures" which took some inputs and did an action. It was considered good programming practice for "functions" not to have side effects. There was no need for them to have side effects because one could always use procedures instead.

So, where else could the term "pure functional" have come from? The answer is - sort of- obvious. It came from impure functional programming languages, the foremost among them being Lisp. Lisp was designed sometime between 1958 and 1960 (between the first and second reports of Algol 60, whose design McCarthy was involved in, but didn't feel satisfied with). Lisp's design was based fundamentally on functional programming. However, it also allowed side-effects as a pragmatic choice. It did not have a notion of a command or a procedure. So, in Lisp, one mostly wrote "pure functions", but occasionally, one wrote "impure functions," i.e., functions with side-effects, to get something done. The terms "pure Lisp" or "purely functional subset of Lisp" have been in use for a long time. Slowly, by osmosis, this idea of "purity" has come to invade all our space.

The imperative programming languages could have resisted the trend. But, once C decided to abolish the idea of "procedures" and call them "void functions" instead, they didn't have much of a leg to stand on.

于 2012-03-24T00:38:22.110 回答
6

它来自“函数”的数学定义,其中函数不可能有副作用。

于 2011-10-13T07:09:45.943 回答
3

为什么用“纯”这个词来描述具有这些属性的函数?

来自维基词典 > pure # 形容词

  • 没有瑕疵或瑕疵;清白的
  • 不含异物或污染物
  • 没有不道德的行为或品质;干净的
  • 科学的一个分支,为自己的利益而做,而不是为另一个科学分支服务。

很明显,交互函数的行为最容易推断何时它们仅受其输入影响,而它们本身仅影响其输出。因此,这些功能不可避免地会受到关注和分类。现在我们可以用什么词来描述具有这些属性的函数?“没有外来物质或污染物”和“没有不道德的行为或品质”似乎很好地描述了这一点。

谁首先以这种方式使用“纯”这个词,什么时候?

我太年轻了,无法自信地回答这个问题。然而,我认为,这个词(或一些非常接近的同义词)将被用来描述以这种方式运行的函数是不可避免的。

有没有其他意思大致相同的词?

您自己说过:“参照透明”。但是,您似乎暗示“参照透明度”仅包含“纯功能”一词的部分含义。我不同意; 我觉得这完全是同义词。来自维基百科>参考透明度

如果一个表达式可以用它的值替换而不改变程序的行为,则称它是引用透明的。(强调我的)

Haskell 社区有时以类似的方式使用形容词“安全”。(请参阅Safe库,以避免引发异常。与 对比unsafePerformIO

我现在想不出任何其他的同义词。

于 2011-10-13T22:22:12.870 回答
2

函数的概念起源于数学。函数的数学概念或多或少是从一个集合到另一个集合的映射。从这个意义上说,函数不可能有副作用;不是因为它们以这种方式“更好”,也不是因为它们被特别定义为没有副作用,而是因为“具有副作用”的概念对于这个函数的定义没有任何意义。数学函数不是执行的一系列步骤,那么这些步骤中的任何一个如何以某种方式“影响”您正在谈论的其他数学对象?

当人们开始研究计算时,他们对机器可实现的算法产生了兴趣,这些算法在给定输入的情况下计算数学函数的值。人们开始谈论可计算函数。但是在计算机中实现的功能 (至少在命令式语言中,这是程序员首先使用的)一系列可执行步骤,显然产生副作用。

因此,程序员很自然地将函数视为算法,而不是数学函数。因此,函数是纯粹的数学函数,数百年来关于函数的所有理论都适用于它,而不是不能以这种方式推理的通用程序员的函数。

于 2011-10-13T23:12:07.093 回答