流れで、いよいよオブジェクト指向に対する懐疑心が無視できないレベルに達した2017年冬。2017「モナド会」とは、モナドをまともに使ったことがない人間が、モナドどころか関数型プログラミングの経験もない人間に、モナドについて解説するという恐ろしい会である。実は以前、モナドについての記事を書いたことがある。氏の論文を読んで、少し分かった気になったので軽い気持ちで書いた記事だ。その後、何の間違いなのか、「モナド」でググるとこの記事が1ページ目に表示されるようになってしまった。本当に申し訳ない気持ちでいっぱいである。この責任ある立場としては、「モナド会」なるものを開催し、分かったつもりの勢いで初心者に解説を試みて、そしてその成果をここで紹介することでより混乱を深めていくしかない、そのように決意した次第である。いうわけで、今回は「モナド会」で説明を試みた話題の中から、最も根本的な話である「そもそもなんで関数型プログラミングが必要なのか?」というお題について紹介してみたい。関数型プログラミングのメリットは、これまでの主流を占めていたオブジェクト指向プログラミングとの比較で考えると分かりやすい。一言で言えば、オブジェクト指向と比較して関数型は「原因と結果を局所化するので、システムの動きが分かりやすくなる」。いうことだろうか?以下の図を見て欲しい。オブジェクト指向では、システムに何か動きがあったとき、その動きの原因となる箇所と、結果となる箇所が分散しているため、システムの動作(状態遷移)が把握しづらくなる。上図で言うと、青い部分が原因になる箇所で、赤い部分が結果として状態変更の行われる可能性のある箇所だ。引数が動作の入力になるというのは、比較的すんなりと理解できる。書かれた箱も青い線で囲まれていて、入力の一部になっていることが分かる。プログラムの外部にあるサービスを表している。状態も事前条件として、動作に影響を与える「原因」の一部になっている。状態変更が起こる可能性があることが分かる。操作するのがプログラムのそもそもの目的なのだから、当たり前と言えば当たり前の事態なのだが、オブジェクト指向言語でユニットテストを書いたことがある人なら、なんとなくこれらの厄介さが分かるのではないだろうか。とあるメソッドのテストを書く場合、単純に引数を渡して実行すればOKというわけには行かず、依存オブジェクトやシステムについて、何らかの準備が必要になることが多い。Testing)といった選択に悩むことになる。Devices(外部サービス)は、プログラムの挙動を予測しづらくする諸悪の根源なのである。関数型では、この原因と結果を、関数の入出力として局所化するため、システムの動きが格段に分かりやすくなる。この原則が徹底されているとき、つまり、システムで発生し得る状態遷移の全てが関数の入出力として表現されてるとき、これらの関数を純粋な関数と呼ぶ。純粋な関数だけで構築されたシステムでは、その入出力として表現されている以外の出来事は起こらない。関数の入出力を見ればシステムがどのように動くかを完全に把握できるということだ。そのようなシステムを図にしたのが以下である。システムが動くときの原因と結果が、関数の入出力として局所化されていることが分かる。操作できなければ、まともなプログラムは作れないはずである。実はそこに純粋関数型プログラミングのトリックがある。