副作用とは
- 関数外への影響
副作用の例
- グローバル変数の書き換え
- ネットワークの向こうのリソースの利用
- DBアクセス
- API呼び出し
- IO
- ファイル入出力
- ソケット通信
副作用のない関数とは
- 引数が同じなら戻り値も同じ
- 関数の外に影響がない
副作用がないと何が嬉しいのか
- テストが書きやすい
- 挙動が予想しやすい
小さいことに思えるが、結局これの積み重ねが堅牢なプログラムに繋がります。
用語
副作用のない関数を「純粋関数」と言ったりします
純粋関数の作り方
- JavaやC#の場合、関数にstaticを付けるとかなり純粋寄りになる
- static変数にはアクセス出来るので注意
- そもそも、よほどのことが無い限りstatic変数は作るべきではない!
- TypeScriptなどはモジュール内の変数は触れてしまう
- モジュールを大きくしすぎない
- スコープを狭くし誤操作が起きにくくする(カプセル化)
余談・Haskellは全てが純粋関数です
純粋関数なんてある?という疑問
- 処理の起点が非純粋な大きな関数になるのは仕方がない
- 業務アプリのロジックはほとんどがDBアクセスを伴う
- 副作用のない機能なんて実際にはほとんどない
非純粋関数から純粋部分を抽出して関数化することには意味がある
純粋関数はテストしやすい
- DBから取得したデータの加工は純粋関数で行う
- 業務ルールを表現したロジックをテスト可能に出来る
パラダイムシフト
- SQLで全てを解決しようとしない
- 純粋関数で処理した方がテストしやすくなる
なおDBの仕事を減らすのは負荷対策の観点でも大事。
最後に
- 副作用のないプログラムはほぼ存在しない
- だが副作用を局所的にすることはできる
- 純粋な処理を分離することは有用