質問

この用語は何ですか 参照透明性 平均?「等しいものを等しいものに置き換えることができることを意味する」と説明されているのを聞いたことがありますが、これは不十分な説明のようです。

役に立ちましたか?

解決

「参照透過性」という用語分析哲学、自然言語の構成要素、ステートメント、および引数を分析する哲学のブランチ論理と数学の方法。言い換えれば、それはプログラミング言語のセマンティクスと呼ばれるものにコンピューターサイエンスの外で最も近い主題です。哲学者 Willard Quine は、参照の透明性の概念を開始する責任がありましたが、バートランドラッセルとアルフレッドホワイトヘッドのアプローチ。

基本的には、「参照の透明性」非常にシンプルで明確なアイデアです。用語「参照先」 式が参照するものについて話すために分析哲学で使用されます。これは、「意味する」という意味とほぼ同じです。または「表記」プログラミング言語のセマンティクス。 Andrew Birkettの例を使用(ブログ投稿)、「スコットランドの首都」という用語エジンバラの都市を指します。これは、「参照先」の簡単な例です。

文のコンテキストは「参照透過的」です。そのコンテキストの用語を同じエンティティを指す別の用語に置き換えても意味は変わりません。例

  

スコットランド議会はスコットランドの首都で開催されます。

は次と同じ意味

  

スコットランド議会はエジンバラで開催されます。

つまり、「スコットランド議会は...で会う」という文脈です参照的に透過的なコンテキストです。 「スコットランドの首都」を置き換えることができます。 「エジンバラ」と意味を変えずに。別の言い方をすれば、コンテキストは用語が何を指しているかだけを気にし、それ以外は何も気にしません。それは、コンテキストが「参照透過的」であるという意味です。

一方、文では、

  

エジンバラは1999年以来スコットランドの首都です。

このような置換はできません。もしそうなら、「エジンバラは1999年以来エジンバラになっています」と言うでしょう。これは言うまでもなく、元の文と同じ意味を伝えません。そのため、「エジンバラは1999年以来...」という文脈にあるように思われます。参照的に不透明(参照的に透明の反対)。この用語が指すものよりも何かを気にかけているようです。なに?

「スコットランドの首都」など。 明確な用語と呼ばれ、長い間論理学者や哲学者に無駄な頭痛を与えませんでした。ラッセルとクインは、実際には「参照」ではない、つまり、上記の例がエンティティを参照するために使用されていると考えるのは間違いだと言って、それらを整理しました。 「エジンバラは1999年以来スコットランドの首都」を理解する正しい方法言うことです

  

1999年以来スコットランドには首都があり、その首都はエディンバラです。

この文は、くだらないものに変換できません。問題が解決しました! Quineの要点は、自然言語は実用的で使いやすいように作られているため、乱雑、または少なくとも複雑であると言うことでしたが、哲学者や論理学者はそれらを正しい方法で理解して明確にする必要があります。参照の透明性は、そのような明快さをもたらすために使用されるツールです。

これはすべてプログラミングと何の関係がありますか?それほど多くはありませんが、実際には。として参照の透明性は、言語の理解、つまり意味の割り当てに使用されるツールであると言いました。プログラミング言語の意味論の分野を設立した Christopher Strachey は、彼の意味の研究にそれを使用しました。彼の基礎論文" プログラミング言語の基本概念" Webで入手できます。それは美しい紙であり、誰もがそれを読んで理解することができます。だから、そうしてください。あなたは非常に啓発されます。彼は「参照の透明性」という用語を紹介しています。この段落では:

  

式の最も有用なプロパティの1つは、Quine参照によって呼び出されるものです   透明性。本質的に、これはfiを望む場合、式の値を見つけることを意味します   部分式が含まれています。部分式について知る必要があるのは   値。内部構造、数値など、部分式の他の機能   およびその成分の性質、それらが評価される順序、またはインクの色   それらが記述されている場合、メイン式の値とは無関係です。

「本質的に」の使用Stracheyはそれを簡単な言葉で説明するために言い換えていることを示唆しています。機能的なプログラマは、この段落を独自の方法で理解しているようです。 「参照の透明性」は他にも9つあります。論文では、しかし、彼らは他のどれについても気にしないようです。実際、Stracheyの論文全体は、命令型プログラミング言語の意味を説明することに専念しています。しかし、今日、関数型プログラマーは、命令型プログラミング言語は参照的に透過的ではないと主張しています。 Stracheyは彼の墓をめくるでしょう。

状況を救うことができます。自然言語は「乱雑、または少なくとも複雑」であると述べました。実用に便利なように作られているからです。プログラミング言語も同じ方法です。それらは「乱雑、または少なくとも複雑」です。実用に便利なように作られているからです。それは彼らが私たちを混乱させる必要があるという意味ではありません。意味を明確にするために、参照的に透明なメタ言語を使用して、正しい方法で理解する必要があります。私が引用した論文で、Stracheyはまさにそれを行っています。彼は命令型プログラミング言語の意味を、それらを基本的な概念に分解することで説明します。彼の分析の重要な部分は、プログラミング言語の式には、 l-values r-values と呼ばれる2種類の「値」があることを指摘することです。 Stracheyの論文以前は、これは理解されておらず、混乱が最高でした。今日、Cの定義はそれを日常的に言及しており、すべてのCプログラマーはその区別を理解しています。 (他の言語のプログラマーがそれを等しくよく理解しているかどうかは言うのが難しいです。)

QuineとStracheyは、何らかの形式のコンテキスト依存を含む言語構成の意味に関心がありました。たとえば、「エジンバラは1999年以来スコットランドの首都」となっています。 「スコットランドの首都」という事実を意味します。それが考慮されている時間に依存します。このようなコンテキスト依存は、自然言語とプログラミング言語の両方で現実です。関数型プログラミングの場合でも、自由変数とバインド変数は、それらが現れるコンテキストに関して解釈されます。あらゆる種類のコンテキスト依存関係は、何らかの方法で参照透過性をブロックします。用語が依存するコンテキストに関係なく用語の意味を理解しようとすると、再びwになってしまいます。

他のヒント

関数型プログラミングで一般的に使用される用語である参照透過性は、関数と入力値が与えられると、常に同じ出力を受け取ることを意味します。つまり、関数で使用される外部状態はありません。

参照透過関数の例を次に示します。

int plusOne(int x)
{
  return x+1;
}

参照透過関数を使用して、入力と関数を指定すると、関数を呼び出す代わりに値で置き換えることができます。したがって、パラメーター5でplusOneを呼び出す代わりに、6に置き換えることができます。

もう1つの良い例は、一般的な数学です。関数と入力値を指定した数学では、常に同じ出力値にマップされます。 f(x)= x +1。したがって、数学の関数は参照的に透過的です。

この概念は研究者にとって重要です。これは、参照的に透過的な関数がある場合、簡単な自動並列化とキャッシングに役立つためです。

参照透過性は、Haskellなどの関数型言語で常に使用されます。

-

対照的に、参照の不透明性の概念があります。これは逆を意味します。関数を呼び出すと、常に同じ出力が生成されるとは限りません。

//global G
int G = 10;

int plusG(int x)
{//G can be modified externally returning different values.
  return x + G;
}

もう1つの例は、オブジェクト指向プログラミング言語のメンバー関数です。メンバー関数は、通常、そのメンバー変数で動作するため、参照不透明です。もちろん、メンバー関数は参照的に透過的です。

さらに別の例は、テキストファイルから読み取り、出力を印刷する関数です。この外部テキストファイルはいつでも変更できるため、関数は参照的に不透明になります。

参照透過関数は、その入力のみに依存する関数です。

[これは関数型/命令型プログラミングの懸念に議論を近づけるための、3月25日からの私の回答に対する追記です。]

機能的なプログラマーの参照透過性の考え方は、次の3つの点で標準的な概念とは異なるようです。

  • 哲学者/論理学者は「参照」、「表示」、「指定」などの用語を使用しますが、および" bedeutung " (Fregeのドイツ語)、機能プログラマーは「値」という用語を使用します。 (これは完全に彼らの行いではありません。Landin、Stracheyとその子孫も用語「value」を使用して参照/表示について話していることに気づきます。LandinとStracheyが導入した単なる用語の単純化かもしれませんが、単純な方法で使用すると大きな違いがあります。)

  • 機能プログラマは、これらの「値」を信じているようです。外部ではなく、プログラミング言語内に存在します。これを行う際に、彼らは哲学者とプログラミング言語意味論者の両方とは異なります。

  • 彼らは、これらの「値」を信じているようです。評価によって取得されることになっています。

たとえば、参照の透明性に関するウィキペディアの記事には、今朝次のように記載されています。

  

式は、プログラムの動作を変更せずに値で置き換えることができる場合(つまり、同じ入力で同じ効果と出力を持つプログラムを生成する)、参照的に透過的であると言われます。

これは哲学者/論理学者の言うこととは完全に異なります。彼らは、そのコンテキスト内の式を同じものを参照する別の expression coreferential 式)に置き換えることができる場合、そのコンテキストは参照または参照透過であると言います。これらの哲学者/論理学者は誰ですか?これらには、 Frege ラッセルホワイトヘッド Carnap Quine 教会など、無数の人々。それぞれがそびえ立つ人物です。これらの論理学者の組み合わされた知的力は、控えめに言っても驚異的です。それらはすべて、正式な言語の外に指示対象/表示が存在し、言語内の表現はそれらについてのみ話すことができるという立場で全会一致です。そのため、言語内でできることは、ある表現を同じエンティティを参照する別の表現に置き換えることだけです。指示対象/表示自体は言語内に存在しません。なぜ機能的なプログラマーは、この確立された伝統から逸脱するのですか?

プログラミング言語の意味論者が誤解した可能性があると推測するかもしれません。しかし、そうではありませんでした。

ランディン

  

(a)各式には   部分式構造のネスト、(b)各部分式   何かを表します(通常は数値、真理値、または   数値関数)、(c)式が示すもの、   つまり、「値」は、そのサブ値の値のみに依存します   他のプロパティではなく式。 [強調を追加]

Stoy

  

式に関して重要なのはその値のみであり、任意の部分式は   その他の値が等しいに置き換えられました[強調を追加]。さらに、式の値sionは、特定の制限内で、発生するたびに同じです。」

鳥とワドラー

  

式の値は、その構成要素の値にのみ依存します   式(存在する場合)およびこれらの部分式は、 othersによって自由に置き換えることができます   同じ値を持つ [強調を追加]。

したがって、振り返ってみると、「参照」/「表示」を置き換えることで用語を簡素化するランディンとストラチーの努力は、 " value"有害だったかもしれません。 「価値」を聞くとすぐに、それにつながる評価プロセスを考えたくなる誘惑があります。評価が「値」として生成するものを考えるのも同様に魅力的ですが、それが表示ではないことは非常に明白かもしれませんが。それが、「参照の透明性」という概念に起こったために私が集めたものです。機能的なプログラマーの目で。しかし、「値」は初期の意味論者が語っていたのは、評価の結果や関数の出力などではありません 。これは用語の意味です。

いわゆる「値」を理解したら、複雑な数学的/概念的なオブジェクトとしての表現(「参照」または「古典的な哲学者の言説における「表示」)の、あらゆる種類の可能性が開かれます。

  • 命令型プログラミング言語の変数を L-values として解釈しました。これは、3月25日の回答で述べたとおり、プログラミング言語の構文内で直接表現されない洗練された概念オブジェクトです。 。
  • 彼はまた、そのような言語のコマンドを状態間関数として解釈しました。これは、「値」ではない複雑な数学オブジェクトの別のインスタンスです。構文内。
  • Cでの副作用のある関数呼び出しでさえ、「値」が明確に定義されています。状態を状態と値のペアにマッピングする状態トランスフォーマー(機能プログラマーの用語では「モナド」と呼ばれます)。

このような言語を「参照透過的」と呼ぶのは、機能的なプログラマーの不本意です。 「値」などの複雑な数学的/概念的なオブジェクトを認めたがらないことを暗示しているだけです。一方、彼らは状態変換を「値」と呼ぶことを完全に喜んでいるようです。自分の好きな構文に入れて、「モナド」のような流行語でドレスアップしたとき。私たちが「参照の透明性」というアイデアを認めたとしても、彼らは完全に矛盾していると言わざるを得ません。ある程度の一貫性があります。

これらの混乱がどのように発生したかについて、少しの歴史がいくらかの光を放つかもしれません。 1962年から1967年までの期間は、クリストファーストラチーにとって非常に集中的な時期でした。 1962年から65年の間、彼はモーリスウィルクスの研究助手としてアルバイトをして、CPLとして知られるようになったプログラミング言語を設計および実装しました。これは必須のプログラミング言語でしたが、強力な関数型プログラミング言語機能も備えていることを意図していました。コンサルタント会社のStracheyの従業員であったLandinは、プログラミング言語に対するStracheyの見解に大きな影響を与えました。 1965年の画期的な論文" Next 700プログラミング言語"で、Landinは機能プログラミング言語をabしげなく宣伝しています(指示的言語)、命令型プログラミング言語を「アンチテーゼ」として説明しています。続く議論では、StracheyがLandinの強い地位に疑問を投げかけていることがわかります。

  

... DLフォーム   すべての言語のサブセット。彼らは

式は、アルゴリズムを変更せずに値で置き換えることができる場合、参照的に透過的であり、同じ入力で同じ効果と出力を持つアルゴリズムを生成します。

参照透過関数は、数学関数のように機能する関数です。同じ入力が与えられると、常に同じ出力を生成します。これは、渡された状態が変更されておらず、関数に独自の状態がないことを意味します。

語源に興味がある場合は、なぜこの概念にこの特定の名前が付いているのか)、私の資料を見てください。 ブログ投稿 話題になっている。この用語は哲学者/論理学者のクワインに由来しています。

簡潔な説明が必要な場合は、危険を冒します(ただし、以下の開示をお読みください)。

プログラミング言語の参照透過性は、等式推論を促進します。参照透明性が高いほど、等式推論を簡単に実行できます。例えば。 (疑似)関数定義を使用して、

f x = x + x、

この定義の範囲内でf(foo)をfoo + fooに(安全に)置き換えることができる容易さは、この削減を実行できる場所にあまり多くの制約がなくても、参照の透明度を示す良い指標ですプログラミング言語が持っています。

たとえば、fooがCプログラミングの意味でx ++である場合、このリダクションを安全に実行できませんでした(つまり、このリダクションを実行する場合、最初のプログラムと同じ結果にはなりません) 。

実用的なプログラミング言語では、完全な参照の透明性は見られませんが、機能的なプログラマーはほとんどのことを気にかけます(Haskellを中核とする目的で参照)。

(完全な開示:私は機能的なプログラマーですので、一番上の答えまでに、この説明を一粒一粒にしてください。)

  1. Denotational-Semanticsは、重要なを構成するドメインを構築することによる言語のモデリングに基づいています。
  2. 関数型プログラマーは、 value という用語を使用して、言語の書き換えルールに基づいた計算の収束を表します。その動作セマンティクス。

1では、問題となっている2つの言語が明確になっています:

  • モデル化されているもの、オブジェクト言語
  • モデリングの言語、メタ言語

2では、オブジェクトとメタ言語が近いため、混同される可能性があります。

言語の実装者として、この区別を常に覚えておく必要があることに気付きました。

だから、レディ教授はこうしてあなたを言い換えることができます:-)

  

関数型プログラミングおよびセマンティクスのコンテキストでは、用語参照   透明性は参照的に透明ではありません。

次の答えは、論争の的となっている第1および第3に追加され、適格であることを願っています 回答。

式が示すまたは参照することを認めましょう いくつかの指示対象。ただし、問題は、これらの参照対象を式自体の一部として同形的にエンコードできるかどうかであり、そのような式を「値」と呼びます。たとえば、リテラル数値は算術式のセットのサブセットであり、真理値はブール式のセットのサブセットなどです。アイデアは式をその値(ある場合)に評価することです。そのため、「値」という言葉は、表現のセットの表示または区別された要素を指す場合があります。しかし、指示対象と値の間に同型(全単射)がある場合、 彼らは同じものだと言うことができます。 (これは、定義するように注意する必要があります 指示の分野で証明されているように、指示対象と同型 セマンティクス。 3番目の回答への返信で言及された例を置くには、 代数的データ型定義 data Nat = Zero | Suc Nat は 自然数のセットに期待どおりに対応します。)

穴がある式の E [·] を書きましょう。 「コンテキスト」として。 Cのような式の2つのコンテキストの例は、 [·] + 1 [·] ++

式を取る(穴のない)関数の [[·]] を書きましょう そしてその意味(指示対象、表示など)をいくつかの 意味を提供する宇宙。 (私はフィールドから表記を借りています 表示的意味論の。)

Quineの定義を次のように形式的に適合させましょう。コンテキスト E [·] E1 E2 の2つの式が与えられた場合、参照的に透過的です(穴がない そこで) [[E1]] = [[E2]] (つまり、式は、 同じ参照先)の場合、 [[E [E1]]] = [[E [E2]]] (つまり、入力 E1 または E2 のいずれかの穴は、同じことを示す式になります 参照先)。

イコールをイコールに置き換えるというライプニッツのルールは、通常、「if E1 = E2 、次に E [E1] = E [E2] '。これは、 E [·] が関数であることを示しています。機能 (またはそのことについては、関数を計算するプログラム)は、 各ソースに対して最大1つのターゲット要素が存在するように、ターゲットへのソース 素子。非決定的関数は誤った呼び名であり、関係、 セットなどを配信する関数。ライプニッツのルールで等式 = が 表示的な場合、二重角括弧は単純に当然のことと見なされ、 省略しました。したがって、参照透過コンテキストは関数です。そして、ライプニッツの規則は等式推論の主要な要素であるため、等式推論は参照の透明性に確実に関連しています。

[[·]] は式から表記までの関数ですが、 式から、値の制限されたサブセットとして理解される「値」までの関数 式、および [[·]] は評価として理解できます。

今、 E1 が式であり、 E2 が値である場合、式、値、および評価。ただし、このページの1番目と3番目の回答に示されているように、これは不正確な定義です。

[·] ++ などのコンテキストの問題は副作用ではありませんが、その値はその意味と同形でCで定義されていません。機能は 関数型プログラミング言語では値であるのに対し、値ではありません(関数へのポインターは)。ランディン、 Strachey、および表示的セマンティクスの先駆者は、 機能的な世界を使用して意味を提供します。

命令型Cライク言語の場合、セマンティクスを(大まかに)提供できます。 表現する

この「意味」の概念は、観察者の心の中で起こることです。したがって、同じ「参照」は人によって違うことを意味します。したがって、たとえば、ウィキペディアにエジンバラの曖昧さ回避ページがあります。

プログラミングのコンテキストで現れる可能性のある関連する問題は、ポリモーフィズムかもしれません。

そして、多相性の特殊なケース(またはキャスト)の名前を付ける必要があるかもしれません。整数型、複合型、または他のさまざまな型のいずれかを使用して表される場合があります-多相的に処理できます)。

参照透過性の定義は、本" コンピュータプログラムの構造と実装"で見つけました。 (ウィザードブック)は、割り当て操作を導入することにより、参照の透明性がどのように侵害されるかの説明によって補完されるため便利です。このテーマについて作成した次のスライドデッキをご覧ください。 https://www.slideshare.net/pjschwarz/introducing-assignment-invalidates-the-substitution-model-of-評価と違反-参照-透明度-説明-SICP-ウィザード本で

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top