web-dev-qa-db-ja.com

純度と参照透過性

用語は定義が異なるように見えますが、私は常に一方が他方を意味すると考えてきました。式が参照透過性であるが純粋ではない場合、またはその逆の場合は考えられません。

ウィキペディアは、これらの概念について個別の記事を維持しており、次のように述べています。

から 参照透過性

式に含まれるすべての関数が純粋関数である場合、式は参照透過性です。また、一部の不純な関数は、それらの値が破棄され、それらの副作用が重要でない場合、式に含めることができます。

から 純粋な式

純粋式を構築するには純粋関数が必要です。 [...]純粋な表現は、参照透過性と呼ばれることがよくあります。

これらのステートメントは紛らわしいと思います。いわゆる「不純な関数」からの副作用が重要ではないので、それらを実行できない場合(つまり、そのような関数の呼び出しをvalue)プログラムを大幅に変更しなくても、そもそも純粋なものと同じですね。

純粋な式と参照透過性の式の違いを理解するためのより簡単な方法はありますか?違いがある場合は、それを明確に示す表現例をいただければ幸いです。

61
Ani

知人の3人の理論家を1か所に集めると、少なくとも2人は「参照透過性」という用語の意味に同意しません。そして、私が若い頃、私のメンターから、専門的な文学だけを考えても、「参照透過性」という言葉は少なくとも3つの異なる意味で使われていると説明する論文がありました。 (残念ながら、その紙はまだスキャンされていない再版の箱のどこかにあります。GoogleScholarで検索しましたが、成功しませんでした。)

私はあなたに知らせることはできませんが、私はできますあきらめるようにアドバイスします:先のとがった言語理論家の小さな幹部でさえそれが何であるかについて同意できないからですつまり、「参照透過性」という用語は役に立たないです。したがって、使用しないでください。


P.S.プログラミング言語のセマンティクスに関係するトピックについては、ウィキペディアは信頼できません。私はそれを修正しようとするのをあきらめました。ウィキペディアのプロセスは、安定性と正確性に対する変化と一般的な投票を考慮しているようです。

41
Norman Ramsey

すべての純粋関数は必然的に参照透過性です。定義上、渡されたもの以外にはアクセスできないため、結果は引数によって完全に決定される必要があります。

ただし、純粋ではない参照透過性関数を持つことは可能です。 int iが与えられ、乱数rを生成し、それ自体からrを減算して、それをsに配置する関数を書くことができます。戻り値 i - s。この関数は乱数を生成しているため、明らかに不純です。ただし、参照透過性があります。この場合、例はばかげて不自然です。ただし、Haskellなどでは、id関数の型はa - > a一方、私のstupidId関数はa -> IO a副作用を利用していることを示します。プログラマーが外部証明によって関数が実際に参照透過性であることを保証できる場合、プログラマーはunsafePerformIOを使用してIOを型から取り除くことができます。

7
sclv

私がここで与える答えは少しわかりませんが、確かに誰かが私たちをある方向に向けるでしょう。 :-)

「純度」は一般的に「副作用の欠如」を意味すると考えられています。評価に副作用がない場合、式は純粋であると言われます。では、副作用は何ですか?純粋に関数型言語では、副作用は単純なベータルール(関数適用を評価するルールは、仮パラメーターのすべての自由な出現を実際のパラメーターに置き換えることと同じです)に従わないものです。

たとえば、線形(または一意性、現時点ではこの区別は気にしない)型の関数型言語では、いくつかの(制御された)突然変異が許可されます。

ですから、「純度」と「副作用」が何であるかを整理したと思います。

参照透過性(あなたが引用したウィキペディアの記事によると)は、変数を、手元のプログラムの意味を変えることなく、それが表す表現(省略形、略語)に置き換えることができることを意味します(ところで、これも取り組むのが難しい質問です、そしてここではそうしようとはしません)。したがって、「純度」と「参照透過性」は確かに異なるものです。「純度」はある式のプロパティであり、大まかに「実行時に副作用を生成しない」ことを意味しますが、「参照透過性」は変数と式に関連するプロパティです。それは「変数はそれが意味するものに置き換えることができる」という意味です。

うまくいけば、これが役立つでしょう。

4

1つのACCU2015トークからのこれらのスライド 参照透過性のトピックに関するすばらしい要約があります。

スライドの1つから:

言語は、(a)すべての部分式をその値と等しい他の部分式に置き換えることができ、(b)特定のコンテキスト内で出現するすべての式が同じ値を生成する場合、参照透過性があります。

たとえば、計算をプログラムの標準出力に記録する関数を使用できますが(したがって、純粋関数ではありません)、この関数の呼び出しを、計算を記録しない同様の関数に置き換えることができます。 。したがって、この関数には参照透過性プロパティがあります。しかし...上記の定義は、スライドが強調しているように、表現ではなく言語に関するものです。

[...]そもそも純粋だったのと同じですね。

私たちが持っている定義から、いいえ、そうではありません。

純粋な式と参照透過性の式の違いを理解するためのより簡単な方法はありますか?

上記のスライド を試してください。

1
vinipsmaker