関数型プログラミングは、変更に柔軟ですか?


関数型言語(scheme)とオブジェクト指向言語(c#)の基礎を同時に勉強し、現在オブジェクト指向と関数指向どちらをより重点的に学んでいくかを考えています。  
オブジェクト指向について、大まかにいえば  
・オブジェクト指向は「変更に強いプログラム」を作るための考え方の一つ。  
・それはプログラムを「責任」という観点でいくつかの「オブジェクト」に分割し、「オブジェクト」同士の相互作用とみること。  
・オブジェクト指向型言語はそれを支援する仕組みを持っている言語。

という考えに落ち着いています。

関数指向については、参照透過性・高階関数について学び、遅延評価を知り、モナドというものがある、ぐらいの断片的な知識に留まっています。

前置きが長くなってすみません。ここで本題に入ります。

  * 「変更に強いプログラムを作る」という考えを関数指向は含んでいるのか？
  * 例え含んでいなくとも、関数型言語にそれをサポートする仕組みがある(これからでる)のか？

ということを知りたいです。




関数型プログラミングは **処理の変更** に、オブジェクト指向は **処理の対象の変更**
に強いという明確な特徴があり、どこに柔軟性を持たせるかによって使い分けるのが望ましいです。

関数型プログラミングは、対象となるデータを定めるのを基本にすることが多く、対象が固定されているために関数を追加、あるいは修正しても一貫性が保たれます。例えば代数的データ型`data
T = A | B |
C`を定義した際、`T`を引数に取る関数は`A`、`B`、`C`すべてに対応すべきで、その条件さえ満たせば「安全な部品」として扱えます。しかし、例えば`A`を`A
Int`に書き換えたりすると今までに作った部品はすべて欠陥品となり、修正しなければいけません。つまり、関数型プログラミングは「データが決まっているという前提の上で、処理を組み合わせたい」という場面で高い柔軟性を発揮しますが、データが決まっていない場合は苦手な傾向があります。

オブジェクト指向の場合はあらかじめ操作(メソッド)を抽象クラス(インターフェイス)にまとめます。それを継承、あるいは実装するクラスは、定められた操作をすべて保証します。関数型プログラミングとは真逆で「操作が決まっているという前提の上で、データを定義したい」という場合に柔軟性を持ち、メソッドを実装してさえいればその中身はどうなっていてもよいのです。一方、アドホックにメソッドを追加しているとクラス間での統一性がなくなり、あっという間に猥雑で理解しにくいプログラムと化してしまいます。

どちらがいいかは目的に強く依存します。論理的なものは関数型で、現実のものを扱う場合はオブジェクト指向で設計するとうまく収まりやすいのではないかと思います。




関数型プログラミングは **処理の変更** に、オブジェクト指向は **処理の対象の変更**
に強いという明確な特徴があり、どこに柔軟性を持たせるかによって使い分けるのが望ましいです。

関数型プログラミングは、対象となるデータを定めるのを基本にすることが多く、対象が固定されているために関数を追加、あるいは修正しても一貫性が保たれます。例えば代数的データ型`data
T = A | B |
C`を定義した際、`T`を引数に取る関数は`A`、`B`、`C`すべてに対応すべきで、その条件さえ満たせば「安全な部品」として扱えます。しかし、例えば`A`を`A
Int`に書き換えたりすると今までに作った部品はすべて欠陥品となり、修正しなければいけません。つまり、関数型プログラミングは「データが決まっているという前提の上で、処理を組み合わせたい」という場面で高い柔軟性を発揮しますが、データが決まっていない場合は苦手な傾向があります。

オブジェクト指向の場合はあらかじめ操作(メソッド)を抽象クラス(インターフェイス)にまとめます。それを継承、あるいは実装するクラスは、定められた操作をすべて保証します。関数型プログラミングとは真逆で「操作が決まっているという前提の上で、データを定義したい」という場合に柔軟性を持ち、メソッドを実装してさえいればその中身はどうなっていてもよいのです。一方、アドホックにメソッドを追加しているとクラス間での統一性がなくなり、あっという間に猥雑で理解しにくいプログラムと化してしまいます。

どちらがいいかは目的に強く依存します。論理的なものは関数型で、現実のものを扱う場合はオブジェクト指向で設計するとうまく収まりやすいのではないかと思います。

