71

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

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

参照透過性から:

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

純粋な表現から:

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

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

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

4

7 に答える 7

52

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

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


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

于 2011-02-11T04:23:22.297 に答える
10

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

ただし、純粋ではない参照透過性関数を持つことは可能です。iintが与えられ、乱数を生成し、それ自体からr減算してに配置し、を返す関数を記述できます。乱数を生成しているため、この関数は明らかに不純です。ただし、参照透過性があります。この場合、例はばかげて不自然です。ただし、たとえばHaskellでは、関数は型であるのに対し、私の関数は副作用を利用していることを示す型になります。プログラマーが外部証明によって関数が実際に参照透過性であることを保証できる場合、プログラマーはを使用してrsi - sida - > astupidIda -> IO aunsafePerformIOIOタイプから離れて。

于 2011-02-02T15:03:56.337 に答える
4

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

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

たとえば、線形(または一意性、現時点ではこの区別は気にしない)タイプの関数型言語では、いくつかの(制御された)ミューテーションが許可されます。

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

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

うまくいけば、これがお役に立てば幸いです。

于 2011-02-02T03:51:52.837 に答える
1

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

スライドの1つから:

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

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

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

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

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

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

于 2015-04-24T13:59:10.300 に答える
0

プログラミング言語でジョンミッチェルコンセプトを引用します。彼は、純粋関数型言語は、副作用や副作用の欠如がない宣言型言語テストに合格する必要があると定義しています。

「x1、...、xnの特定の減速の範囲内で、変数x1、...、xnのみを含む式eのすべての出現は同じ値を持ちます。」

言語学では、名前または名詞句は、含まれる文の意味を変更せずに、同じ指示対象を持つ別の名詞句に置き換えることができる場合、参照的に透過的であると見なされます。

これは、最初のケースでは当てはまりますが、2番目のケースでは奇妙になりすぎます。

ケース1:「ウォルターが彼の新しいに乗り込むのを見た。」

そして、ウォルターがセントロを所有している場合、与えられた文のそれを次のように置き換えることができます。

「ウォルターが彼のセントロに入るのを見た」

最初とは反対に:

ケース#2:彼は彼のあごひげを読んだためにウィリアムルーファスと呼ばれました。

ルーファスはやや赤を意味し、イギリスのウィリアム4世への言及でした。

「彼は彼のあごひげを読んだのでウィリアム4世と呼ばれました。」ぎこちなく見えます。

従来の言い方では、プログラムの意味を変更せずに、プログラム内のどこかで1つの式を同じ値の別の式に置き換えることができれば、言語は参照透過性になります。

したがって、参照透過性は純粋な関数型言語の特性です。また、プログラムに副作用がない場合は、このプロパティが保持されます。

ですから、あきらめることは素晴らしいアドバイスですが、この文脈ではそれを身につけることも見栄えがするかもしれません。

于 2014-12-05T17:39:54.520 に答える
0

標準の良いところは、選択できる標準が非常に多いことです。

アンドリュー・S・タネンバウム。

...参照透過性の定義とともに:

  • Ian HolyerによるMirandaを使用した機能プログラミングの176ページから:

    8.1価値観と行動

    純粋な関数型言語のセマンティクスの最も重要な特性は、次のように、言語の宣言型ビューと運用ビューが正確に一致することです。


    すべての式は値を示し、考えられるすべてのプログラムの動作に対応する値があります。任意の
    コンテキストで式によって生成される動作
    は、その値によって完全に決定され、その逆も同様です。

    この原則は、通常はかなり不透明に参照透過性と呼ばれますが、次のように表現することもできます。

    参照透過性の画像

  • F.ウォーレンバートンによる関数型プログラミング言語の参照透過性を伴う非決定性から:

    [...]式が同じ環境で常に同じ値を持つという特性[...]

...他のさまざまな定義については、 HaraldSøndergaardとPeter Sestoftによる参照透過性、明確性、および展開可能性を参照してください。

代わりに、「純度」の概念から始めます。まだ知らなかった3人にとって、これを読んでいるコンピューターまたはデバイスは、本質的にエフェクトに関連するコンピューティングのモデルであるソリッドステートチューリングマシンです。したがって、すべてのプログラムは、機能的であろうとなかろうと、ThingsDoneTMを取得するためにこれらのエフェクトを使用する必要があります。

これは純度にとってどういう意味ですか?CPUのドメインであるアセンブリ言語レベルでは、すべてのプログラムが不純です。あなたがアセンブリ言語でプログラムを書いているなら、あなたはそれらすべての効果の間の相互作用をマイクロ管理している人です-そしてそれは本当に退屈です!

ほとんどの場合、コンピュータのメモリ内でデータを移動するようにCPUに指示しているだけです。これにより、個々のメモリ位置の内容が変更されるだけで、そこには何も表示されません。目に見える変化(画面にテキストが表示される)を観察するのは、命令がCPUにたとえばビデオメモリへの書き込みを指示した場合のみです。

ここでの目的のために、エフェクトを2つの大まかなカテゴリに分割します。

  • 画面、スピーカー、プリンター、VRヘッドセット、キーボード、マウスなどのI/Oデバイスに関連するもの。一般に観察可能な効果として知られています。
  • 残りは、メモリの内容を変更するだけです。

この状況では、純度とは、実行中のプログラム、場合によってはそのホストコンピューターの環境に目に見える変化を引き起こす、観察可能な影響がないことを意味します。すべての効果がないわけではありません。そうでない場合は、ソリッドステートチューリングマシンを交換する必要があります。


さて、42 の生命、宇宙、そして「参照透過性」という用語が正確に意味するすべての問題について、猫を放牧して理論家を同意させようとするのではなく、この用語に与えられた本来の意味を見つけてみましょう。私たちにとって幸いなことに、この用語はHaskellのI / Oのコンテキストで頻繁に表示されます-関連する記事のみが必要です...ここに1つあります:OwenStephenの機能I/Oへのアプローチの最初のページから:

参照透過性とは、外部式の値を変更せずに、部分式を等しい値の1つに置き換える機能を指します。Quineに由来するこの用語は、Stracheyによってコンピュータサイエンスに導入されました。

参照に従う:

  • クリストファー・ストレイチーのプログラミング言語の基本概念の39ページ中9ページから:

    式の最も有用なプロパティの1つは、Quineの参照透過性によって呼び出されるプロパティです。本質的に、これは、部分式を含む式の値を見つけたい場合、部分式について知る必要があるのはその値だけであることを意味します。内部構造、コンポーネントの数と性質、評価される順序、または書き込まれるインクの色など、サブ式の他の機能は、メインの値とは無関係です。表現。

  • ウィラードヴァンオーモンドクインの言葉と目的の314ページの163ページから:

    [...]このように用語の参照力を中断する引用は、参照透過性の失敗と言えます2。[...]単一の用語tの出現が用語または文ψt)で純粋に参照であるときはいつでも、それが包含用語または文で純粋に参照である場合、私は閉じ込めモードΦを参照透過性と呼びます。 ψt))。

    脚注付き:

    2この用語は、Whitehead and Russell、2d ed。、vol。1、p。665。

その参照に続いて:

  • アルフレッド・ノース・ホワイトヘッドとバートランド・ラッセルによるプリンキピア・マテマティカの719ページの709ページから:

    アサーションが発生すると、それは、主張された命題のインスタンスである特定の事実によって行われます。しかし、この特定の事実は、いわば「透明」です。それについては何も言われていません、それによって少し他の何かについて何かが言われています。真理関数で発生する命題に属するのは「透明な」品質です。

それらすべてをまとめてみましょう。

  1. ホワイトヘッドとラッセルは「透明」という用語を紹介しています。
  2. 次に、Quineは修飾された用語「参照透過性」を定義します。
  3. 次に、Stracheyは、プログラミング言語の基本を定義する際にQuineの定義を適応させます。

したがって、Quineの元の定義またはStracheyの適応された定義のどちらかを選択できます。必要に応じて、Quineの定義を自分で翻訳してみることができます。「純粋関数型」の定義に異議を唱えたことがある人なら誰でも、 「封じ込めモード」や「純粋参照型」が実際に何を意味するのかなど、別のことを議論する機会を楽しむかもしれません。楽しい!私たちの残りの部分は、Stracheyの定義が少し曖昧であることを受け入れ(「本質的に[...]」)、続けます。

式の有用な特性の1つは、参照透過性です。本質的に、これは、部分式を含む式の値を見つけたい場合、部分式について知る必要があるのはその値だけであることを意味します。内部構造、コンポーネントの数と性質、評価される順序、または書き込まれるインクの色など、サブ式の他の機能は、メインの値とは無関係です。表現。

(私が強調します。)

その説明(「 [...]の値を見つけたい場合」)に関して、同様の、しかしより簡潔なステートメントが、次の700プログラミング言語のPeterLandinによって与えられています。

式が示すもの、つまりその「値」は、その部分式ののみに依存し、それらの他のプロパティには依存しません。

したがって:

式の有用な特性の1つは、参照透過性です。本質的に、これは、式が示すもの、つまりその「値」が、その部分式の他のプロパティではなく、その部分式ののみに依存することを意味します。

Stracheyはいくつかの例を提供します:

  • (12/39ページ)

    3_x_ 2 + 2_x_ + 17などの式の記号xは、発生するたびに同じものを表す(または同じ値を持つ)と自動的に想定する傾向があります。これは参照透過性の最も重要な結果であり、前のセクションで説明したwhere句またはλ式を使用できるのはこのプロパティのおかげです。

  • (および16ページ)

    関数が使用される(または呼び出されるか適用される)場合、f [ ε ]と記述します。ここで、εは式にすることができます。参照透過性の言語を使用している場合、 f [ ε ]を評価するために式εについて知る必要があるのは、その値だけです。

したがって、Stracheyの元の定義によると、参照透過性は純粋さを意味します-評価の順序がない場合、観察可能な効果やその他の効果は実際には役に立たない...

于 2021-09-30T00:20:48.490 に答える
0

純粋関数は、すべての呼び出しで同じ値を返す関数であり、副作用はありません。

参照透過性とは、バインドされた変数をその値に置き換えても、同じ出力を受け取ることができることを意味します。

純粋で参照透過性の両方:

def f1(x):
    t1 = 3 * x
    t2 = 6
    return t1 + t2

なぜこれが純粋なのですか?

これは入力のみの機能であり、x副作用がないためです。

なぜこれが参照透過性なのですか?

次のように、ステートメントのそれぞれの右側に置き換えt1て、t2入力することができます。f1return

def f2(x):
    return 3 * x + 6

そして、それでも常にすべての場合f2と同じ結果を返します。f1

純粋ですが、参照透過性ではありません:

f1次のように変更してみましょう。

def f3(x):
    t1 = 3 * x
    t2 = 6
    x = 10
    return t1 + t2

を右側に置き換えて同じトリックをもう一度試して、それがと同等の定義であるかどうかを確認しt1てみましょう。t2f3

def f4(x):
    x = 10
    return 3 * x + 6

これは簡単に観察でき、変数を右側/値に置き換えることと同等ではありませんf3。戻り、戻ります。f4f3(1)9f4(1)36

参照透過性ですが、純粋ではありません

次のようf1に、の非ローカル値を受け取るように変更するだけです。x

def f5:
    global x
    t1 = 3 * x
    t2 = 6
    return t1 + t2

以前と同じ交換演習を実行すると、f5参照透過性が維持されます。ただし、渡された引数のみの関数ではないため、純粋ではありません。

f3注意深く観察すると、からへの参照透過性が失われる理由は、変更されf4ているためxです。一般的なケースでは、変数(または、 sの代わりにsfinalを使用するScalaに精通しているもの)を作成し、不変オブジェクトを使用すると、関数を参照透過性に保つのに役立ちます。これにより、それらは代数的または数学的な意味での変数のようになり、フォーマル検証に適しています。valvar

于 2022-02-06T21:11:04.737 に答える