8937


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

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

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

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

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

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


CC BY-SA 3.0
2015-03-22T06:43:22.907
8231
2015-04-09T06:13:34.147
2015-03-22T10:02:11.673
7460
7460
question
c# scheme
関数型プログラミングは、変更に柔軟ですか?


プログラミング言語やスタイルの種類が、変更に柔軟かどうか直接的に繋がることはありません。

プログラムという言葉を「pro」と「gram」に分割すると「前もって」と「書く」という意味が根源的に含まれていることがわかります。

プログラムという言葉はよくコンピュータ用語で使われますが、あらかじめ実行する内容を定めた予定表や計画書のことも「プログラム」なんて言いますよね。

つまり、いろんなことを想定して前もって用意されているものを「プログラム」と言い、いろんなことを想定して前もって用意する行為を「プログラミング」というのではないでしょうか。

変更に柔軟であるということは、前もって想定して用意しておく（プログラミングする）ということと密接です。

「関数型プログラミングは変更に柔軟なのか」という質問は、「日本語と英語のどちらを使えば人として礼儀正しくなれるのか？」というような奇妙な質問に少し似ている気がします。

> オブジェクト指向はトップダウンで、関数型プログラミングはボトムアップだ！

というような表現をされている記事を以前見たことがありますが、この表現に乗っかった意見を述べるならば、トップダウンよりもボトムアップで開発しているほうが、前もって想定していなくても、足元に前もって用意されたものがあって、それらを使えることがあるから柔軟であるといえるのかもしれません。（自分で発言していてかなり不安ですが）

個人による開発であれば、言語やプログラミングスタイルによる柔軟性への影響は通常より大きいような気がしますが、チームによる開発になった場合には、恐らくどれだけ変更に柔軟かどうかは、どれだけ素晴らしいチームワークを築けるかなのではないかなと個人的に思うところが強いです。


CC BY-SA 3.0
2015-03-22T09:23:31.167
8234
2015-03-22T18:35:04.250
2015-03-22T18:35:04.250
8351
8351
8231
answer


関数型言語でも、オブジェクト指向言語でも、変更に強いプログラムの作成は、可能です。  
それは言語の問題ではなく、プログラマの技量の問題です。  
ヘボなプログラマなら、どの言語を使おうが、変更に強いプログラムを作成するのは不可能でしょう。逆に、優秀なプログラマなら、どんな言語を使おうと、変更に強いプログラムの作成が可能でしょう。

あと、関数型言語とオブジェクト指向言語は相反するものではありません。  
関数型言語を用いてオブジェクト指向プログラミングをすることは可能ですし(例えばCommon
lispや一部のScheme処理系)、逆にオブジェクト指向言語を用いて関数型プログラミングをすることも可能です(例えばScala)。

Ps:
kazurego7様はどうやらHaskellを勉強しているようですね。個人的な見解ですが、関数型言語に入門するのにHaskellは不向きだと思います。Haskellは、特殊すぎる(くせがありすぎる)プログラミング言語だからです。関数型言語に入門するのなら、Schemeが一番いいと思います。またオブジェクト指向入門なら、Javaが最適です。


CC BY-SA 3.0
2015-03-22T16:04:39.607
8237
2015-03-22T16:04:39.607
5970
8231
answer


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

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

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

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


CC BY-SA 3.0
2015-04-09T06:13:34.147
8937
2015-04-09T06:13:34.147
2826
8231
answer