【さんしょうとうかせい】

参照透過性 とは?

💡 同じ問いには必ず同じ答え。裏で何も変えない「律儀な自動販売機」のような性質
📌 このページのポイント
参照透過性: 同じ入力 → 必ず同じ出力 参照透過(純粋関数) add(2,3) → 5 add(2,3) → 5 add(2,3) → 5 いつでも 必ず 同じ! 非参照透過(副作用あり) getTime() 10:00 getTime() 10:05 getTime() 10:10 毎回 結果が 違う! 参照透過性のメリット テストが簡単 入出力だけ確認すればOK デバッグしやすい 実行順序を気にしない 並列処理が安全 データ競合が起きない
参照透過性の対比とメリットのイメージ
ひよこ ひよこ

参照透過性って難しそうな名前だけど、どういう意味なの?

ペンギン先生 ペンギン先生

簡単に言うと「同じ入力なら必ず同じ結果を返す」性質のことだよ。自動販売機で例えると、100円を入れてボタンを押したら、いつ何回やっても同じジュースが出てくるイメージ。裏でこっそり在庫を変えたりもしないんだ。

ひよこ ひよこ

普通の関数でもそうなんじゃないの?

ペンギン先生 ペンギン先生

実はそうでもないんだ。たとえば現在時刻を返す関数は、呼ぶたびに違う値が返るよね。グローバル変数を書き換える関数も、呼ぶ順番で結果が変わってしまう。こういう「副作用」があると参照透過性が崩れるんだよ。

ひよこ ひよこ

参照透過だと何がうれしいの?

ペンギン先生 ペンギン先生

大きなメリットが3つあるよ。まずテストが簡単になる。入力と出力だけ確認すればいいから。次にデバッグがしやすい。関数を呼んだ順番や状態を気にしなくていいからね。そして並列処理が安全になる。複数スレッドから同時に呼んでもデータが壊れないんだ。

ひよこ ひよこ

でも実際のアプリって、データベースに書き込んだりファイルを保存したりするよね?

ペンギン先生 ペンギン先生

そう、現実のプログラムには副作用が必要だよね。だから関数型言語のHaskellでは「モナド」という仕組みで副作用を管理しているんだ。純粋な計算部分と副作用のある部分を明確に分離することで、参照透過な部分のメリットを最大限に活かすんだよ。

ひよこ ひよこ

モナドって聞いたことある!参照透過性と関係してたんだね!

ペンギン先生 ペンギン先生

そうだよ。ちなみに参照透過性の正式な定義は「任意の式をその評価結果で置換してもプログラムの意味が変わらない」こと。これを「置換モデル」と呼ぶんだ。コンパイラが最適化する際にも、参照透過な式は安全に並べ替えやメモ化ができるから、パフォーマンス面でも有利なんだよ。

ペンギン
まとめ:ざっくりこれだけ覚えればOK!
「参照透過性」って出てきたら「同じ入力なら絶対に同じ出力で、副作用もない性質」と思えればだいたいOK!
📖 おまけ:英語の意味
「Referential Transparency」 = 参照の透過性
💬 「referential(参照の)」+「transparency(透明さ)」で、式の中身が透明に見通せる=置き換えても問題ないという意味合いだよ
← 用語集にもどる