純粋関数とは?

関数型プログラミングにおいて、純粋関数(Pure Function)とは、同じ入力に対して必ず同じ出力を返し、外部の状態を変更しない関数のことです。
純粋関数は、外部の変数や状態に依存せず、関数の外側へ影響を与えません。そのため、結果を予測しやすく、テストやデバッグがしやすいという特徴があります。
純粋関数の特徴
純粋関数には、主に次の2つの特徴があります。
| 特徴 | 説明 |
|---|---|
| 入力が同じなら出力も常に同じ | 同じ引数を与えれば、何度実行しても同じ結果を返します。 |
| 副作用がない | 外部の変数、DOM、ファイル、通信などを変更しません。 |
この2つを満たす関数が、純粋関数と呼ばれます。
純粋関数の例
次のadd()関数は、純粋関数の基本的な例です。
function add(a, b) {
return a + b;
}
console.log(add(2, 3));
このadd()関数は、2と3を渡すと常に5を返します。
外部の変数を変更せず、外部の状態にも依存していないため、純粋関数といえます。
副作用とは?
副作用(Side Effect)とは、関数が外部の状態に影響を与えることです。
代表的な副作用には、次のようなものがあります。
- 外部変数の値を変更する。
- DOMを書き換える。
- コンソールへ出力する。
- API通信を行う。
- ファイルやデータベースへ書き込む。
副作用がある関数は、必ず悪いというわけではありません。実際のアプリケーションでは、画面更新や通信などの副作用は必要です。ただし、副作用が多すぎると、処理の流れが追いにくくなります。
副作用を持つ関数の例
次の関数は、外部の変数を変更しているため、副作用を持っています。
let count = 0;
function increment() {
count++;
}
increment();
console.log(count);
increment()関数は、関数の外側にあるcountを変更しています。
このように、関数の外部に影響を与える処理は副作用です。
純粋関数と副作用の比較
純粋関数と副作用を持つ関数の違いを整理すると、次のようになります。
| 比較項目 | 純粋関数 | 副作用を持つ関数 |
|---|---|---|
| 外部状態への影響 | なし | あり |
| 出力の一貫性 | 同じ入力なら常に同じ出力を返す | 外部状態によって結果が変わることがある |
| テストのしやすさ | 入力と出力だけを確認すればよい | 外部状態も考慮する必要がある |
| デバッグのしやすさ | 原因を追いやすい | どこで状態が変わったか追いにくいことがある |
副作用を避ける理由
副作用を持つ関数が増えると、コードの動作を予測しにくくなります。
特に大規模なアプリケーションでは、どの処理がどの状態を変更しているのか分かりにくくなり、不具合の原因を見つけるのが難しくなります。
そのため、すべての処理を純粋関数にする必要はありませんが、計算処理やデータ変換処理はできるだけ純粋関数として書くと、保守しやすいコードになります。
副作用を回避する例
外部変数を直接変更する代わりに、新しい値を返すようにすると、副作用を避けやすくなります。
function incrementPure(count) {
return count + 1;
}
const result = incrementPure(0);
console.log(result);
この例では、countを直接変更せず、新しい値を戻り値として返しています。
このように書くと、関数の動作が入力と出力だけで決まるため、理解しやすくなります。
配列を変更しない純粋関数の例
配列を扱う場合も、元の配列を直接変更しないようにすると、純粋関数に近い形で書けます。
function addItem(items, newItem) {
return [...items, newItem];
}
const fruits = ["Apple", "Banana"];
const newFruits = addItem(fruits, "Cherry");
console.log(fruits);
console.log(newFruits);
この例では、fruits配列を直接変更せず、新しい配列を作成して返しています。
push()を使うと元の配列が変更されますが、スプレッド構文(...)を使うことで、元のデータを保ったまま新しい配列を作成できます。
初心者が覚えておきたいポイント
- 純粋関数は、同じ入力に対して常に同じ出力を返します。
- 純粋関数は、外部の変数や状態を変更しません。
- 副作用には、DOM操作、API通信、外部変数の変更などがあります。
- 副作用は悪ではありませんが、扱う場所を整理することが重要です。
- 計算処理やデータ変換処理は、できるだけ純粋関数にすると保守しやすくなります。
まとめ
- 純粋関数は、同じ入力に対して常に同じ出力を返す関数である。
- 純粋関数は、外部状態を変更しない。
- 副作用とは、関数が外部の状態に影響を与えることである。
- 副作用が多いコードは、動作の予測やデバッグが難しくなりやすい。
- 外部変数を直接変更せず、新しい値を返すことで副作用を減らせる。
- 純粋関数を意識すると、テストしやすく保守性の高いコードを書きやすくなる。