参照透過性とは? わかりやすく解説

参照透過性

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2025/07/09 15:30 UTC 版)

参照透過性(さんしょうとうかせい、: Referential transparency)は、計算機言語の概念の一種である。あるが参照透過であるとは、その式をその式の値に置き換えてもプログラムの振る舞いが変わらない(言い換えれば、同じ入力に対して同じ作用と同じ出力とを持つプログラムになる)ことを言う。具体的には変数の値は最初に定義した値と常に同じであり、関数は同じ変数を引数として与えられれば同じ値を返すということになる。当然変数に値を割り当てなおす演算である代入 (Assignment) を行う式は存在しない。このように参照透過性が成り立っている場合、ある式の値、例えば関数値、変数値についてどこに記憶されている値を参照しているかということは考慮する必要がない、即ち参照について透過的であるといえる。

参照透過性が成り立つ言語は式の値がプログラムのテキストから定まるという特徴から宣言型言語 (Declarative language) と呼ばれたりする。一方変数の値の変更が認められているような参照透過的でない言語を手続き型言語と呼ぶ。ただ、手続き型言語は機械語プログラミングとの繋がりという歴史的な事情により手続きが式でなく命令列で表現されたことから命令型言語と呼ばれることもあり、そのような場合との対比で単に式(例えば関数や変数の組み合わせ)でプログラムが表現されているだけの言語、あるいは高階関数の仕組みを備えた言語をひっくるめて、代入が可能であるかないかを問わず、関数型言語と呼ぶことも多い。結局現状では単に関数型言語という場合は参照透過的な言語(即ち純粋関数型言語)とそうでない関数型言語を両方とも含むということになっている。

また以上に関連して分散処理を記述する場合に、あるデータがどのノード上にあるかを意識せず透過的にアクセスできるという性質も参照透過性と呼ばれる[要出典]

代入と参照透過性を取り巻く技術的課題

参照透過性が成り立つような言語では変数の値を定義する構文はあっても変数の値を再定義するような変数への代入 (Assignment) を行う構文は存在せず、ある式の値、例えば関数値、変数値についてどこに記憶されている値を参照しているかということを考慮する必要がない。

ただこのような違いがありながらも参照透過性の有無は、計算理論上は言語の記述能力を左右しない。代入はプログラム、またその要素である関数内での変数の変更を許す、つまり内部状態を作るため数学的にはチューリングマシンのような状態機械でモデル化できる一方、純粋関数型言語はラムダ計算でモデル化できるが、両者で記述できるプログラムの集合は同一であることが証明されているからである。とはいえ、人間にとっての記述しやすさ、可読性、現時点の技術で実現した場合の実行効率などは両者で当然異なる。

例えば関数値、変数値についてどこに記憶されている値を参照しているかということを考慮する必要がないということは記憶領域の使い方の管理がプログラマの手から完全に離れているということを意味するため、プログラムの表現を簡明にすることに寄与する一方で、実行効率向上のためには言語処理系によるデータの管理と最適化を多分に必要とする。具体的な例を挙げれば、参照透過性が成り立つような言語では大きなデータ構造(例えば要素数の多い配列レコード型など)の極一部を変更するような場合でも主記憶上にあるデータ構造の一部だけを単純に書き直すことが出来ない(例えばAとBが同じ式で配列として定義されているときにBの3番目を変更したらAの3番目をアクセスする式の値がどうなるか)。

また、当然のことながら参照透過性が成り立つような言語では参照され共有されている記憶領域に格納された値を監視するようなコードは書けない。このことはプログラムの動作を副作用の考察なしに追跡し、その実行をスケジューリングできるというようにプログラム理解を簡単にし最適化の可能性を広げる一方で、変数で同期を取るような素朴な並行・並列処理プログラムは最早書けず、入力動作を表現するためには様々な工夫が必要となり、スケジューリングに左右されないように出力を順序正しく行うためにも様々な工夫が必要となることを意味する。

以上のような理由からMLのように、基本的には関数型を指向して作られていながら補助的に代入の機能も備え、式に状態を持たせられるようにするケースがしばしばある。Haskellではモナド (Monad) 型と構文糖衣を利用して参照透過性を保ったまま手続き型的な表現を可能にしている。また、Haskellと相互に影響を与え合ったもう一つの純粋関数型言語Cleanでは、一度参照したら二度と参照しないという一意性をその値の型に付加属性として与え、代入を利用しつつ参照透過性を維持し、効率化も実現している。

参照透過性の解釈の変化

Haskellでは上述のような問題点を解決するための試みがなされ、新しい仕様であるHaskell 2010でSTモナドとして結実した。参照透過性を満たす関数は引数が同じなら同じ値を返すものであるから、代入を使ってもその性質を満たし、なおかつ他の計算にも影響しなければよいとするものである。わかりやすい例として再帰関数がある。合計や階乗などは代入を使った反復であっても、与えられた引数が同じなら結果も同じである。代入をその関数の内部だけにとどめ、結果の取得は変数の内容をコピーして返す関数を使わせることで、確実に副作用から切り離すといった工夫を盛り込んだ。これがSTモナド(State Transformerモナド)である。

参考文献

関連事項


参照透過性

出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2022/01/06 04:20 UTC 版)

関数型プログラミング」の記事における「参照透過性」の解説

詳細は「参照透過性」を参照 参照透過性とは、数学的な関数同じように同じ値を返す式を与えたら必ず同じ値を返すような性質である。次の square 関数は、 2 となるような式を与えれば必ず 4 を返し、 3 となるような式を与えれば必ず 9 を返しいかなる状況でも別の値を返すということはなく、これが参照透過性を持つ関数一例となる。 def square(n): return n ** 2 次countup 関数は、同じ 1 を渡しても、それまでcountup 関数どのような引数呼ばれていたかによって、返り値1, 2, 3, ... と変化するため、引数の値だけで結果の値が定まらないような参照透過性のない関数であり、数学的な関数とはいえない。 counter = 0def countup(n): global counter counter += n return counter 参照透過性を持つことは、その関数が状態を持たないことを保証する。状態を持たない数学的な関数は、並列処理実現するのに適している。関数型プログラミング言語の内で、全ての関数が参照透過性を持つようなものを純粋関数プログラミング言語という。

※この「参照透過性」の解説は、「関数型プログラミング」の解説の一部です。
「参照透過性」を含む「関数型プログラミング」の記事については、「関数型プログラミング」の概要を参照ください。

ウィキペディア小見出し辞書の「参照透過性」の項目はプログラムで機械的に意味や本文を生成しているため、不適切な項目が含まれていることもあります。ご了承くださいませ。 お問い合わせ


英和和英テキスト翻訳>> Weblio翻訳
英語⇒日本語日本語⇒英語
  

辞書ショートカット

すべての辞書の索引

「参照透過性」の関連用語

参照透過性のお隣キーワード
検索ランキング

   

英語⇒日本語
日本語⇒英語
   



参照透過性のページの著作権
Weblio 辞書 情報提供元は 参加元一覧 にて確認できます。

   
ウィキペディアウィキペディア
All text is available under the terms of the GNU Free Documentation License.
この記事は、ウィキペディアの参照透過性 (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。 Weblio辞書に掲載されているウィキペディアの記事も、全てGNU Free Documentation Licenseの元に提供されております。
ウィキペディアウィキペディア
Text is available under GNU Free Documentation License (GFDL).
Weblio辞書に掲載されている「ウィキペディア小見出し辞書」の記事は、Wikipediaの関数型プログラミング (改訂履歴)の記事を複製、再配布したものにあたり、GNU Free Documentation Licenseというライセンスの下で提供されています。

©2025 GRAS Group, Inc.RSS