web-dev-qa-db-ja.com

関数型プログラミングはコードを複雑にしますか?

過去1年間、私は Scala コード(Javaバックグラウンドからのもの)を書いています。valsを使用して、よりシンプルでクリーンなコードを作成する方法がとても気に入りました、caseクラス、map/filter/lambda関数、暗黙的関数、および型推論。 Akka ベースのアプリケーションで主に使用しました。

今年は、Scalaプロジェクトで、関数型プログラミングが本当に好きな新しいチームと一緒にいます。彼らは Scalaz を頻繁に使用しており、コードはどこにでも適用されます。コンテキストの境界、リーダー/ライター/状態モナド、メインのメソッドでさえI/Oモナドに「ラップ」されています。その理由は、これによりコンパイラーがコードが正しいことを主張する際にコンパイラーが「機能する」ようになり、各関数が副作用がない。

それでも、私の見解では、このすべての構文はビジネスロジックの邪魔になります。たとえば、「MyBusinessObject」のタイプは問題ありません。「List [MyBusinessObject]」、「Option [MyBusinessObject]」、「Future [MyBusinessObject]」などのタイプも同様です。それらはすべて明確な意味と目的を持っています。一方、次のようなコード:

def method[M[_]: Applicative] = {
  case (a, b) => (ca[M](a) |@| cb[M](b)) {
    case t @ (ra, rb) =>
      if (ra.result && rb.result) t.right
      else t.left
  }
}

それはプログラムを複雑にしますか、それとも私がこのプログラミング方法に慣れていないのは私だけですか?

17
Luciano

これはnothingが関数型プログラミングと関係しています-他のプログラミング言語との関連でこの種の状況を見つけることができます-開発者が「自分の」言語の高度な構成を愛していて常識を無視している開発者読みやすさとシンプルさの維持について。 C、C++、Perl、Java、C#、Basic、その他の非関数型言語でこのような状況に遭遇しました。コードに複雑さを加えるのは関数型プログラミングではありません-プログラマはそうします。

誤解しないでください。高度な言語機能を使用しないことはお勧めしません。ただし、特定のコンテキストで適切なバランスを見つけることが重要です。世界中で100,000人を超える開発者が使用する汎用ライブラリを作成する場合、ローカルオフィス専用の個別のレポートジェネレーターを作成する場合とは異なる方法が適用されます。

37
Doc Brown

彼らがコーディングする方法に慣れていないのは、少なくともその一部です。私はあなたと同じような状況にあり(C#からF#に入り、Haskellのバックグラウンドを持つ人々と一緒に作業しています)、面白い経験をしていると思いますが、壁に頭をぶつけて、もつれをほどく瞬間があります。何が起こっているのかを把握するために、特に複雑なポイントフリー関数構成。それは文化的なものです。

この特定のコードがプログラムを複雑にするかどうかについては、わかりません。一般的なコードはそれ自体複雑になる可能性があることに同意しました。しかし、それはユーティリティであり、ビジネスロジックの一部ではありません。コードベースが複雑になるか単純になるかを知りたい場合は、そのコードなしでどのように見えるかを想像する必要があります。このような一般的な構成では、それら自体が複雑になることがよくありますが、1つの画面に収めることができるのは複雑です。同時に、コードベース全体をかなり単純にします。これは特にモナドの場合です。

繰り返しになりますが、@ Doc Brownが示唆するように、それは「芸術のための芸術」の場合にもなり得ます。それを除外することもできません。

7
scrwtp

一般的な関数型プログラミングでは、可変状態を排除することで複雑さを軽減、コードのセクションがどのように機能するかを理解しようとするときに考慮しなければならないケースの数を減らすと主張します。

ただし、関数型プログラミングはより高度な抽象化を可能にします。高度に抽象化されたコードは非常に有用ですが、通常、理解を導くために通常使用するコンテキストから切り離されているため、理解するのが難しい場合もあります。ビジネスオブジェクトに関する「すべてに明確な意味と目的がある」というコメントは間違いなく真実ですが、そのロジックはすでに理解しているニーズとコンテキストに非常に固有であるという事実を反映しています。モナドのような構造の存在はあなたが少しの努力で非常に有用な何かを作ることを可能にします、しかしモナドが何であるかを説明しようとするページがウェブに散らばっています。それはあなたのための抽象化です。

また、Scalazは、長い間FPを食べたり呼吸したりしている人々によって書かれました。彼らはHaskellで利用可能な機能をScalaに持ち込もうとしました。そうすることで、彼らは教育的であるように試みませんでした。 Scalazは、著者にとっては明確で簡単なように見えますが、初心者には異質な語彙とスタイルを利用しています。私たちの残りの部分を困惑させる方法は、Haskellのバックグラウンドを考えると、作者には非常に明白であるように見えたので、コメントすらしませんでした。

さらに、関数型プログラミング言語として、Scalaには shortcomings (JVMに欠点があるため)があり、Scalazの作者に醜いコードを書かざるを得ない場合がありました。たとえば、一般的な末尾呼び出しの排除がないため、一部のコードではトランポリンを使用する必要があり、「親切なシステム」がないと型シグネチャが複雑になる可能性があります。

そして最後に、Scalazはそれ自体をうまく利用しています。それはその力のしるしと考えることができますが、初心者にとっては、ソースをパズルにする可能性があります-ランダムに見たコードの断片は、他人に見える他の何かを利用する可能性があります。

頑張れ。そして this が役立つかもしれません。

5
AmigoNico