回答:
ウィキペディアには、関数型プログラミングに関する素晴らしい記事があり、 いくつかの例があります。@Konrad RudolphはすでにOOP記事へのリンクを提供しています。
あるパラダイムが他のパラダイムのスーパーセットであるとは思わない。それらはプログラミングに関する異なる観点であり、いくつかの問題はある観点からよりよく解決され、いくつかは別の観点からよりよく解決されます。
あなたの質問は、FPとOOPのすべての実装によってさらに複雑になります。各言語には、質問に対する適切な回答に関連する独自の癖があります。
ますます接線のとりとめ:
Scalaのような言語は、両方の長所を提供しようとするという考えが気に入っています。私はそれがあなたに両方の世界の合併症を与えることを心配しています。
Javaはオブジェクト指向言語ですが、バージョン7には、一種のクロージャーを模倣するために使用できる「try-with-resources」機能が追加されました。ここでは、別の関数の途中でローカル変数「a」を更新することを模倣しますが、その関数からは見えません。この場合、他の関数の前半はClosureTry()コンストラクターであり、後半はclose()メソッドです。
public class ClosureTry implements AutoCloseable {
public static void main(String[] args) {
int a = 1;
try(ClosureTry ct = new ClosureTry()) {
System.out.println("Middle Stuff...");
a = 2;
}
System.out.println("a: " + a);
}
public ClosureTry() {
System.out.println("Start Stuff Goes Here...");
}
/** Interface throws exception, but we don't have to. */
public void close() {
System.out.println("End Stuff Goes Here...");
}
}
出力:
Start Stuff Goes Here...
Middle Stuff...
End Stuff Goes Here...
a: 2
これは、ストリームを開き、ストリームに書き込み、確実に閉じるという意図した目的、または2つの関数の間で何らかの作業を行った後に2番目の関数を呼び出すことを忘れないように単純にペアリングするという目的に役立ちます。もちろん、非常に新しく異常なため、別のプログラマーが何かを壊していることに気付かずにtryブロックを削除する可能性があるため、現在は一種のアンチパターンですが、実行できるのは興味深いことです。
ほとんどの命令型言語のループは再帰として表現できます。オブジェクトと変数は不変にすることができます。副作用を最小限に抑えるためにプロシージャを書くことができます(ただし、コンピューターでは真の機能は不可能だと主張します-実行にかかる時間と、それが消費するプロセッサー/ディスク/システムリソースは避けられない副作用です)。一部の関数型言語は、すべてではないにしても多くのオブジェクト指向操作を実行するように作成できます。一部の言語には特定のパターン(可変フィールドなど)を妨げる制限(変数の更新を許可しないなど)がありますが、これらは相互に排他的である必要はありません。
私にとって、オブジェクト指向プログラミングの最も有用な部分は、データの隠蔽(カプセル化)、同様の十分なオブジェクトの処理(ポリモーフィズム)、およびデータとそのデータを一緒に操作するメソッド(オブジェクト/クラス)の収集です。継承はOOPのフラッグシップかもしれませんが、私にとっては、これは最も重要ではなく、最も使用されない部分です。
関数型プログラミングの最も有用な部分は、不変性(変数ではなくトークン/値)、関数(副作用なし)、およびクロージャーです。
オブジェクト指向だとは思いませんが、コンピューターサイエンスで最も役立つことの1つは、インターフェイスを宣言し、さまざまな機能とデータでそのインターフェイスを実装できることです。また、いくつかの可変データを処理したいので、すべてのプログラム設計で可変性と副作用を制限しようとしても、関数型言語だけでは完全に快適ではないと思います。