関数型プログラミングとは以下のようなものです
- __純粋関数(pure function)__だけを使ってプログラムを構築することが前提
- 純粋関数と__副作用(side effect)__のない関数のことを指す
副作用の定義はとりあえず置いておくとして、副作用の例として以下のようなものがあります
- 変数を変更する(変数への再代入/forループのカウンタなども)
- データ構造を直接変更する(list.addなど)
- オブジェクトのフィールドを設定する(setterパターンなど)
- 例外をスローする
- ファイルの読み込み・書き込み
- 画面への描画
以上のようなことは、大抵は言語レベルではできてしまいます。 したがって関数型プログラミングは、__副作用のないプログラムを書くという制約をプログラマ自身が課す__という側面があるかもしれません。
関数型プログラミングはプログラムの書き方を制約するものではあるのですが、表現可能なプログラムの種類を制約するものではありません。 したがって副作用のない記述をしなければならないという制約のもと、I/Oを実行したりエラーを処理したり、データを変更したりするためにはどうしたら良いのかということを知っていないと難しい部分があります。
関数型プログラミングは書き方を制約するプログラミングスタイルですが、その利点はどういったものになるのでしょうか。例として以下のようなものがあります。
- 純粋関数を用いることによりモジュール性が向上する
- モジュール性が高いのでテストしやすい
- モジュール性が高いので再利用しやすい
- モジュール性が高いので並列化しやすい
- モジュール性が高いので一般化しやすい
- モジュール性が高いので推論が容易
- バグが発生しにくくなる(状態を持たないので)
ここでいう関数とは、__入力に基づいて結果を計算することを除いて、プログラムの実行に対して観察可能な効果を与えない__もののことを言うことにします。これはようするに副作用がないということです。
__参照透過性(referential transparency)__と__純粋関数(pure function)__を次のように定義します
式 e がありすべてのプログラム p において、p の意味に影響を与えることなく、p 内のすべての e を e の評価結果と置き換えることができるとしてら、e は参照透過です。関数 f があり、式 f(x) が参照透過なすべての x に対して参照透過ならであるとしたら、f は純粋関数です。