純粋な関数とは、副作用のない関数です。どのような種類の I/O も実行できず、状態を変更することもできません。また、参照透過的です。同じ入力で複数回呼び出された場合、常に次の結果が返されます。同じ出力。
これらのプロパティを持つ関数を説明するために「純粋」という言葉が使用されるのはなぜですか? そのように「純粋」という言葉を最初に使ったのは誰で、いつですか? ほぼ同じことを意味する他の単語はありますか?
純粋な関数とは、副作用のない関数です。どのような種類の I/O も実行できず、状態を変更することもできません。また、参照透過的です。同じ入力で複数回呼び出された場合、常に次の結果が返されます。同じ出力。
これらのプロパティを持つ関数を説明するために「純粋」という言葉が使用されるのはなぜですか? そのように「純粋」という言葉を最初に使ったのは誰で、いつですか? ほぼ同じことを意味する他の単語はありますか?
最初の質問に答えるために、数学関数は、いくつかの指定された変数に関して「純粋」であるとしばしば説明されてきました。例えば:
最初の項はxの純関数で、2 番目の項はyの純関数です。
このため、真の「最初の」オカレンスは見つからないと思います。
プログラミング言語については、少し検索すると、Ada 95 ( pragma Pure
)、High Performance Fortran (1993) ( PURE
)、およびVHDL-93 ( pure
) のすべてに「純粋関数」の形式的な概念が含まれていることがわかります。
Haskell (1990) はかなり明白ですが、純度は明確ではありません。GCC の C には、さまざまな異なるレベルの「純粋」に対するさまざまな関数属性があります。
数冊の本: Rationale for the C プログラミング言語(1990) はこの用語を使用しており、Programming Languages and their Definitions (1984) も同様です。ただし、どちらも使用回数は 1 回のみのようです。Programming the IBM Personal Computer, Pascal (同じく 1984) はこの用語を使用していますが、Google の制限されたビューからは、Pascal コンパイラがそれをサポートしていたかどうかは明らかではありません。(そうではないと思います。)
興味深いことに、Ada の前身である Green は、実際にはかなり厳密な「関数」定義を持っていました。メモリの割り当てさえ許可されていませんでした。ただし、これは関数が副作用 (I/O またはグローバル変数) を持つことができるが引数を変更できない Ada になる前に削除されました。
C28-6571-3 (コンパイラの前に書かれた最初の PL/I リファレンス マニュアル) は、PL/I がREDUCIBLE
(= pure) 属性の形式で、1966 年にさかのぼって最初にリリースされました。(これは 3 番目の質問にも答えます。)
この最後のドキュメントはREDUCIBLE
、ドキュメント C28-6571-2 以降の新しい変更として含まれていることを明確に示しています。そのREDUCIBLE
ため、おそらくプログラミング言語における正式な純粋関数の最初の化身であり、1966 年 1 月から 7 月にかけて登場しました。
更新: この意味での Google グループの「純粋な関数」の最初のインスタンスは1988 年のものであり、書籍の参照を簡単に遅らせることができます。
いくつかの神話:
「純粋関数」という用語は、すべての関数が本質的に「純粋」である数学に由来するものではありません。そのため、何かを「純粋関数」と呼ぶ必要はまったくありませんでした。
この用語は、命令型プログラミングに由来するものではありません。Fortran、Algol 60、Pascal などの初期の命令型プログラミング言語には、常に 2 種類の抽象化がありました。入力に基づいて結果を生成する「関数」と、入力を受け取ってアクションを実行する「プロシージャ」です。「関数」が副作用を持たないことは、良いプログラミングの実践と考えられていました。代わりにいつでもプロシージャを使用できるため、副作用が生じる必要はありませんでした。
では、「純粋関数型」という用語は他にどこから来たのでしょうか? 答えは - ある意味 - 明白です。それは、Lisp を筆頭に、純粋でない関数型プログラミング言語から生まれました。Lisp は 1958 年から 1960 年の間に設計されました (Algol 60 の最初の報告と 2 番目の報告の間で、McCarthy はその設計に関与していましたが、満足していませんでした)。Lisp の設計は、基本的に関数型プログラミングに基づいていました。ただし、実際的な選択として副作用も許容されます。コマンドや手順の概念はありませんでした。そのため、Lisp では、主に「純粋な関数」を書きましたが、時折、何かを成し遂げるために「不純な関数」、つまり副作用のある関数を書きました。「純粋な Lisp」または「Lisp の純粋に機能的なサブセット」という用語は、長い間使用されてきました。
命令型プログラミング言語は、この傾向に抵抗できた可能性があります。しかし、C が「プロシージャ」の概念を廃止し、代わりに「void 関数」と呼ぶことを決定すると、C には根拠がほとんどありませんでした。
これは、「関数」の数学的な定義に由来し、関数が副作用を持つことはあり得ません。
これらのプロパティを持つ関数を説明するために「純粋」という言葉が使用されるのはなぜですか?
ウィクショナリーより > 純 # 形容詞
- 欠陥や欠陥がないこと。汚れのない
- 異物や汚染物質がない
- 不道徳な行動や資質がないこと。掃除
- 別の科学分野に奉仕するのではなく、それ自体のために行われる科学分野の。
相互作用する関数の動作は、関数が入力のみに影響され、それ自体が出力のみに影響を与える場合に最も簡単に推論できることは明らかです。したがって、この種の機能が注目され、分類されることは避けられません。では、そのような特性を持つ関数を説明するためにどのような言葉を使用できますか? 「異物や汚染物質がないこと」と「不道徳な行動や性質がないこと」は、これをかなりうまく説明しているようです。
そのように「純粋」という言葉を最初に使ったのは誰で、いつですか?
私は若すぎて、これに自信を持って答えることができません。しかし、このように振る舞う機能を説明するために純粋という言葉(または非常に近い同義語) が使用されることは避けられなかったと私は主張します。
ほぼ同じことを意味する他の単語はありますか?
あなたはそれを自分で言いました:「参照透過性」。ただし、「参照の透過性」は「純粋な関数」というフレーズの意味の一部のみを含むと示唆しているようです。同意しません; まったく同義だと感じます。ウィキペディアから> 参照透過性:
プログラムの動作を変更せずに式をその値に置き換えることができる場合、その式は参照透過的であると言われます。(私のものを強調)
Haskell コミュニティは、「安全」という形容詞を同様の方法で使用することがあります。(例外のスローを回避するために作成されたSafeライブラリを参照してください。 と対比してくださいunsafePerformIO
)
他に同義語は今のところ思いつきません。
関数の概念は数学に端を発しています。関数の数学的概念は、多かれ少なかれ、あるセットから別のセットへのマッピングです。この意味で、関数に副作用があることは不可能です。そのように「より良い」からではなく、副作用がないように明確に定義されているからではなく、「副作用がある」という概念がこの関数の定義では意味をなさないからです。数学関数は実行される一連のステップではないので、これらのステップのいずれかが、あなたが話している他の数学オブジェクトに何らかの形で「影響を与える」ことができるでしょうか。
人々が計算の研究を始めたとき、彼らは入力を与えられた数学関数の値を計算するための機械で実行可能なアルゴリズムに興味を持つようになりました。人々は計算可能関数について話し始めました。ただし、コンピューターに実装されている関数 (少なくとも、プログラマーが最初に使用した命令型言語)は一連の実行可能ステップであり、明らかに副作用が発生する可能性があります。
そのため、プログラマーは関数を数学関数ではなくアルゴリズムとして考えるのが自然になりました。したがって、純粋関数は純粋に数学関数であり、そのように推論できない一般化されたプログラマーの関数とは対照的に、関数に関する数百年の理論すべてが適用されます。