「純粋な」関数の標準的な定義はありますか?


9

StackOverflowは私をここに指し示したので、質問は一般人の言葉では少しかもしれません。

ウィキペディアは純粋な関数を次のように定義しています

コンピュータプログラミングでは、関数に関するこれらのステートメントが両方とも成立する場合、関数は純粋な関数として記述できます。

  1. 関数は常に、同じ引数値が指定された同じ結果値を評価します。関数の結果値は、プログラムの実行が進むにつれて、またはプログラムの異なる実行間で変化する可能性のある非表示の情報や状態に依存したり、I / Oデバイスからの外部入力に依存したりすることはできません。
  2. 結果の評価は、変更可能なオブジェクトの変異やI / Oデバイスへの出力など、意味的に観察可能な副作用や出力を引き起こしません。

ただし、出典を引用しているようには見えないため、これが受け入れられた定義であるのか、誰がこのように定義したのかを判断するのは困難です。

「純粋な」関数の構文/注釈が言語に含まれているときの言語の動作を見ると、かなりいくつかの異なるアプローチがあります。

  1. Dでは、唯一の制限はグローバル状態の非変異です。「純粋な」関数はその引数を変更できます。
  2. GCCには、「純粋」の2つのタイプがあります:(pure副作用はありませんが、グローバルな状態を読み取ることができます)およびconst(Wikipediaの定義に従って厳密に純粋です)。
  3. C#では、「目に見える状態の変更を行わない」(それが何であれ)と定義されています。
  4. HaskellはWikipediaの定義に従います。

だから私の質問は、純粋な関数の標準的な定義はありますか?
そして、もしあるなら、その源は何ですか?


関連する歴史的視点。ただし、明確な、または出典が明かされた回答はありません。
ギルデンスタン2014

1
これは答える価値はありませんが、ここに私の定義があります。x= y(定義による)の場合、fx = fyはtrueであり、fは外部で測定可能な状態の変化を引き起こしません(つまり、状態のすべての変化はx、yの内部にあります)。およびf)。Haskellはこれを利用します。サンクを変更し、結果をすぐに返す関数に置き換えることで、遅延評価を実装しています。つまり、(fx)を評価した場合、実際には内部でfとxが変わる可能性がありますが、これはわかりません。
Jake 14

回答:


3

この論文で述べたように、Payton-JonesとWadler(Haskellを作成した研究者グループの1人)によるImperative Functions Programming(1993)は次のとおりです。

2つの理由から、副作用を排除する純粋に機能的なソリューションに焦点を当てています。まず、副作用がないため、方程式の推論とプログラム変換を無制限に使用できます...

プログラムの変換を可能にする副作用(つまり、コンパイラの最適化)がないことが焦点です。

副作用とは何ですか?次に、このペーパーは、GiffordとLucassenによる関数型プログラミングと命令型プログラミングの統合(1986)を示し、4つのタイプのエフェクトクラス(Pure、Function、Observer、およびProcedure)について説明しています。したがって、「純粋な関数」という用語はこの論文に由来します。

  • PUREは参照透過的です。副作用は発生せず、その値は副作用の影響を受けず、評価されるたびに同じ値を返します。

ただし、Peyton-JonesとWadlerがこのアプローチの欠点に言及したことに注意してください。注目に値するのは、線形型を使用して安全な方法(つまりコンパイラにとって安全)で副作用を導入するプログラミング言語Cleanです。基本的に、メインエントリポイントを含むすべてのI / O関連関数の変数としてWorldをスレッド化します。

これにより、純粋な関数型言語が世界と相互作用し、副作用(I / O、OS、ウィンドウシステムなど)を持ち、ウィキペディアの定義と部分的に矛盾する可能性があります。実際、Haskellはインフルエンサーの1つとしてCleanを持っていると言えます。ただし、線形型から離れ、別の型レベルの構成体(モナド)を使用して線形性を保証します(つまり、常に単一参照)。


「基本的に、それは変数として世界をスレッド化します...」。あなたは実際に「スレッド」を意味しますか?これに関する非公式の説明はウェブ上にありますか?
14

「スレッディング」をメタファーとして使用しました。つまり、World変数をある関数から別の関数に渡す必要があります。また、線形型付けとは、そのようなワールド変数が2回以上使用されないことを意味します。たとえば、関数内でファイルを開くには(f_handle, world2) = fopen file_name, world(疑似コード)、次の呼び出しではを使用する必要があることを意味しますworld2。本質的に、プログラムは宇宙全体で機能していると見なされています。
言い換えれば

あなたが言うように、世界をスレッド化することは、(私が覚えているように)表示セマンティクスで環境を処理する標準的な方法のようです。したがって、重要な点は線形性でなければなりません。ただし、意味論的意味論(DS)は、線形性の制約なしに、純粋に機能的であると想定されています。DSは数学的な抽象概念であり、多くの世界をジャグリングすることに何の問題もないと思います。コンピューティングは物理的であり、線形性は世界の進化を可能にしますが、一度に存在できる世界は1つだけです(これはおそらく評価を逐次化します)。同時に実行される2つのCleanプログラムのセマンティクスは何ですか:-)?
バブー14

ギフォードとルカセンの論文はウェブで閲覧できますか?
バブー14

ユニからアクセスしました。
カルロサヤム2014

-1

ウィキペディアの定義は標準的です。重要な2つの要件は次のとおりです。

  • 関数の戻り値と動作は、関数に明示的に渡された引数の確定的な関数です。

  • 関数の呼び出しには、目に見える副作用はありません。

厳密に言えば、Dとgccは「純粋な」という言葉を彼らのように使うべきではありません。これは、標準的な用語の乱用です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.