読者です 読者をやめる 読者になる 読者になる

関数型プログラミングとオブジェクト指向について思うこと

大学時代に関数型言語を扱っていたため、私は関数型プログラミングが大好きです。
そのため、現代のプログラミングの標準であるオブジェクト指向プログラミング(以下、OOP)にあまり興味が湧いてきませんでした
しかし、2014年はGUIプログラミングに手を伸ばした過程で、OOP関数型プログラミングの棲み分けについて思うところがありました。今回はそれを書き留めてみようと思います。

関数型プログラミング

関数型プログラミング」の言葉の意味はwikipediaを見てください。関数型プログラミングにおける“関数”は、数学の“関数”です。
http://ja.wikipedia.org/wiki/%E9%96%A2%E6%95%B0%E5%9E%8B%E8%A8%80%E8%AA%9E

関数型プログラミングの魅力

非関数型の言語を使う方でも分かりやすい魅力として、「副作用のない関数」を扱うスタイルが挙げられます。
副作用のない関数によりプログラムを組み上げることにより、「扱う状態を少なくする」ことと「実行順序に依存しない処理を書ける」ことで、バグを少なくすることができます。

扱う状態を少なくする

副作用のない関数によってプログラムを組み立てる関数型プログラミングでは、オブジェクト指向と比較して、状態の重要性が小さいです。
扱う状態数が多くなるほど、その管理が難しくなります。状態の管理を誤るとプログラムになることから、プログラムの状態を少なくすることはバグを少なくすることに繋がる、と言えます。

実行順序に依存しない処理を書ける

Haskellで遅延評価が実現できるように、関数型プログラミングでは「どのような順序で処理するか」はあまり重要視されていません。
オブジェクト指向(というよりも手続き型言語)では、状態を処理する順序によって、得られる結果が変わる場合があるため、本来不要な実行順序の制約が処理に付与される場合があります。そのため、必要以上に実行順序の制約が入りやすくなり、処理の組換えなどが困難になる傾向にある、と思われます。
関数型プログラミングでよく使われる副作用のない関数は、入力が等しいなら得られる結果も等しいことが保障されます。そのため、処理の組換え、部品化が容易です。また、実行順序にとらわれない処理が明確になるため、並行化できる領域も抽出しやすくなります。

オブジェクト指向関数型プログラミングよりも優れている点

以下は私の感覚です。

オブジェクト指向が得意とする領域は、以下のような点が挙げられる、と考えています。
・状態を扱う必要がある領域
・実行順序を制御する必要がある領域
これは、画面(GUI)制御やデバイス制御がこれにあたります。

実世界に近い部分(人が触る部分(=GUI)や機械が触る部分(=デバイス制御))はオブジェクト指向プログラミングが向いている領域と考えています。実世界における個々の状態を、オブジェクトの状態として容易に表現できます。
対して、状態を管理する必要がない領域はできる限り論理的に、数学的に記載することで、バグを少なくできます。関数型プログラミングビジネスロジックを記載することに向いていると考えます。
Separated Presentationにおける、プレゼンテーションロジックはオブジェクト指向(+手続き型プログラミング)で、ビジネスロジック関数型プログラミングで記載すると良いのでは、と考えています。

まとめ

オブジェクト指向だけでも、どんなアプリケーションでも作ることができます。しかし、オブジェクト指向では万物がオブジェクトであれば、それを管理しするプログラマは神でなければならないのか、とも思います。
全てのオブジェクトを一切のミスなく管理するには、まさに神のような能力が必要になると思います。しかし、それは多くの人には困難です。
現実世界における科学の如く、関数型プログラミングはプログラムの世界をより抽象化し、人間に扱いやすくできると考えています。
オブジェクト指向、手続き型、関数型プログラミングが得手不得手があるので、どれか一つを覚えれば十分、ではなく適材適所に扱えることが必要なのだと思いました。