Writing へ戻る
Software

純粋関数

概要

純粋関数(Pure Function)とは、「入力だけが出力を決める関数」です。 言い換えると、同じ入力を与えれば、常に同じ結果を返す冪等性 (idempotecy) のある関数です。

この性質は、非常にシンプルな機械に例えることができます。

  1. 入力:データを受け取る唯一の場所
  2. エンジン(関数本体):入力データのみを使用して計算する
  3. 出力:計算結果を返す唯一の場所

この構造により、『関数の出力が、その入力のみによって決定される』という状態が成立します。

Pure functionx = 3x = 3x = 3f(x)x × 2666same inputevery timealways same outputdoes not read or mutate external stateImpure functionexternal: countx = 3x = 3g(x)x + count++reads & mutates45same input,different resultdepends on & mutates external stateTwo core rules of pure functions① Referential transparencyf(3) always returns the same valuecall can be replaced by its result② No side effectsI/O, global vars, DB writes NGzero impact on the outside worldBenefits of pure functionsEasy to test · Safe to parallelize · Memoizable · Easy to debugExamples of side effects (avoided in pure functions)· console.log() calls (I/O)· Mutating global variables or objects· HTTP requests, DB writes, file operations

純粋関数のルール

純粋関数は、以下の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

なぜ重要か

純粋関数は、保守性・拡張性の高い実装に欠かせない概念です。

  • デバックが容易:バグの原因が「その関数外」にないことを保証できます
  • テストが簡単:外部状態の準備(モックなど)が不要です
  • 並列化が容易:データの競合(副作用)が発生しません
  • メモ化が可能:同じ入力なら常に同じ結果なので、キャッシュできます

参考