純粋関数
概要
純粋関数(Pure Function)とは、「入力だけが出力を決める関数」です。 言い換えると、同じ入力を与えれば、常に同じ結果を返す冪等性 (idempotecy) のある関数です。
この性質は、非常にシンプルな機械に例えることができます。
- 入力:データを受け取る唯一の場所
- エンジン(関数本体):入力データのみを使用して計算する
- 出力:計算結果を返す唯一の場所
この構造により、『関数の出力が、その入力のみによって決定される』という状態が成立します。
純粋関数のルール
純粋関数は、以下の2つの性質を持ちます。
副作用がない
- 関数実行中に、戻り値を返すこと以外に行われる『外部世界のやり取り』を副作用と呼びます
- 副作用がある関数は不純(Impure)です(例:グローバル変数の書き換え・例外を投げる)
参照透過性
- 参照透過性とは『ある式をその実行結果(値)で置き換えても、プログラム全体の挙動が変われない』性質です
- 例:
f(x) + f(x)を2 * f(x)と置き換えても安全です
サンプルコード
純粋関数:
# Pure def add(a, b): return a + b # Pure def multiply(x, y): return x * y # Pure (mathematical) def square(n): return n * n
不純関数:
# Impure - uses external state counter = 0 def increment(): global counter counter += 1 return counter # Impure - side effect (printing) def say_hello(name): print(f"Hello, {name}!") # side effect # Impure - depends on current time import datetime def get_current_year(): return datetime.datetime.now().year # Impure - mutates input def add_to_list(lst, item): lst.append(item) # mutates the original list return lst
なぜ重要か
純粋関数は、保守性・拡張性の高い実装に欠かせない概念です。
- デバックが容易:バグの原因が「その関数外」にないことを保証できます
- テストが簡単:外部状態の準備(モックなど)が不要です
- 並列化が容易:データの競合(副作用)が発生しません
- メモ化が可能:同じ入力なら常に同じ結果なので、キャッシュできます