プログラミングを学んでいると、「純粋関数」という言葉を耳にすることがあります。
でも、こんな疑問を持つ人も多いと思います。
- 純粋関数って何が“純粋”なの?
- 普通の関数と何が違うの?
この記事では、初心者の方でも理解できるように、純粋関数の定義・特徴・メリット・非純粋関数との違いを、具体例を交えてわかりやすく解説します。
純粋関数とは?

純粋関数は、次の3条件を満たす関数です。
- 同じ入力(引数)に対して、常に同じ出力を返す
- 外部の変数や環境に依存しない
- 副作用が発生しない
つまり、純粋関数は「外の状態に依存せず、外の状態を変えない関数」です。ではここから、上記の各条件について詳しく説明します。
補足
- 純粋関数の対義語は非純粋関数です。
- 純粋関数は英語で「Pure function」と言います。
- 非純粋関数は英語で「Impure function」と言います(「Non-pure function」と言う場合もありますが「Impure function」が一般的です)。文脈によっては「副作用を持つ関数」なので「Effectful function」や「Side-effecting function」と呼ぶこともあります。
同じ入力(引数)に対して、常に同じ出力を返す
純粋関数は、入力(引数)が同じなら、何度呼んでも結果は変わりません。以下にサンプルコードを示します。
def square(x):
return x * x
print(square(3)) # 9
print(square(3)) # 9(毎回同じ結果)このsquare()関数は「純粋関数」です。なぜなら、結果は引数xの値だけで決まり、外部の変数や環境に依存していないからです。
外部の変数や環境に依存しない
純粋関数は、外部の変数や環境に依存しません。
例えば、以下のadd_to_base()関数は一見シンプルですが、baseという外部の変数を使っています。そのため、baseの値が変わると、同じ引数xを渡しても出力が変わってしまいます。このように、外部の変数に依存して結果が変わる関数は「純粋関数」ではなく、「非純粋関数」になります。
base = 10
def add_to_base(x):
return x + base副作用が発生しない
副作用(side effect)とは、関数の外の世界(外部)に影響を与えることを指します。
たとえば次のような処理はすべて副作用です。
- 外部の変数を変更している
- ファイルやデータベースに書き込む
- コンソールに出力する(print()など)
- 画面を更新する
- ネットワーク通信を行う
これらは「関数の外部」に影響を及ぼすため、副作用があります。そのため、これらの処理がある関数は「純粋関数」ではなく「非純粋関数」となります。一例を見てみましょう。
外部の変数を変更している
count = 0
def increment():
global count
count += 1
return countこの関数は呼び出すたびにcountの値が変わります。つまり、同じ入力でも結果が変わるため、これは「純粋関数」ではありません。「非純粋関数」です。
コンソール出力やログ出力を行う
def greet(name):
print(f"Hello, {name}!") # 出力という副作用print()は外部(標準出力)に文字を表示する処理なので、これも副作用を持ちます。したがって、この関数も「純粋関数」ではありません。「非純粋関数」です。
純粋関数のメリット
純粋関数のメリットを以下に示します。
メリット
- 動作が予測しやすい
- 同じ入力なら、常に同じ出力を返します。
- 純粋関数は外部の状態に左右されないため、バグを特定しやすく、安心して呼び出せます。
- テストが簡単
- 外部の状態を気にせず、引数と戻り値だけを確認すればOKです。関数単体のテストが非常に簡単になります。
- 例:
assert square(2) == 4
- 再利用性が高い
- 外部依存がないため、どの環境でも同じように動作します。
- そのため、純粋関数はモジュール化・再利用に向いています。
- 並列実行でも安全(スレッドセーフ)
- 純粋関数は外部の状態を変更しないので、複数スレッドから同時に呼び出しても問題ありません。
「純粋関数」と「非純粋関数」の違い
「純粋関数」と「非純粋関数」はどちらも関数ですが、性質がまったく違います。
繰り返しになりますが、大きな違いは次の3つです。
- 同じ入力(引数)に対して、常に同じ出力を返すか
- 外部の変数や環境に依存しないか
- 副作用(外への影響)が発生するか
つまり、純粋関数は「中で完結する関数」、非純粋関数は「外と関わる関数」と覚えるとわかりやすいです。
以下に違いを表形式でまとめます。
| 純粋関数 | 非純粋関数 | |
| 同じ入力での出力 | 常に同じ | 変わる可能性あり |
| 外部への依存 | なし | あり |
| 副作用 | なし | あり |
| テストのしやすさ | 〇(引数と戻り値だけ確認すればOK) | △(外部状態を考慮する必要あり) |
| 並列実行の安全性 | 〇(スレッドセーフ) | ×(外部状態を変更する恐れあり) |
本記事のまとめ
この記事では『純粋関数』について、以下の内容を説明しました。
純粋関数は、
- 同じ入力なら常に同じ出力を返し、
- 外部に依存せず、
- 副作用を持たない
という3つの特徴を持つ関数です。
この性質のおかげで、純粋関数はテストしやすく、再利用しやすく、並列実行にも強いという大きなメリットがあります。
お読みいただきありがとうございました。