関数型プログラミングとOOPについての議論をやめる

投稿には一定量の冗談が含まれており、厚生省は準備ができていない読者に読書を控えるよう説得力をもって求めている。



「AFの方が良い」または「OOPの方が良い」に関する記事は、ランチ、フォーク、またはスプーンに最適なものに関する議論に似ています。 伝統的に、6月はスプーンで始まりましたが、かつて非常に権威のある人が肉だけを食べてフォークを使うと言っていたので、新しいファッションが生まれました-フォークで食べます。 おridgeやスープを食べ、スムージーを作ることさえできます。 インターネットには、フォークでスムージーを食べて、すべての熊手を克服することを学んだという記事が散らばっています。 これは面白いだけでなく、悲しいことでもあります。一方で、この誇大宣伝を無視するだけで素晴らしい結果を見せている経験豊富な男性に競争上の優位性をもたらします。 この記事では、絶対的な真実であると主張していませんが、実際には非常にうまく機能している私のビジョンを伝えようとします



科学の慣習として、定義から始めます。 OOPの古典的な定義には、継承、カプセル化、およびポリモーフィズムの原則に従うことが含まれます。 しかし、これらのコンポーネントのいずれかがない場合、OOPになりますか? そうでない場合、それは何になりますか? 観客の退屈な部分は、この非現実的で私たちに何の質問も与えないで浮かびまし たが、PLOの前に何が起こったかを思い出し てください 。 そして彼の前は手続き型プログラミングでした。 そして、当時のOOPの主なアイデアは、処理のためのデータと関数の接続にありました 。 アイデアはシンプルですが、非常に革新的で、いくら想像するのは難しいですが、それについては後で詳しく説明します。



関数型プログラミングは、自由な解釈では、 プログラムを数式と見なします。 数式は形式化されており、同じ入力で同じ出力が返されます。 プログラム全体は、同じ原則に従うルーチンで構成されています。 これは同じ手続き型プログラミングとどう違うのですか? FPは純粋関数を積極的に使用します ;理想的には、プログラム全体が純粋関数であるべきです。 純粋な関数には副作用がなく 、簡単にメモしたり、簡単にテストしたりできます。...純粋な関数では、FPの主なアイデアと利点が言えると言えます。



そして今、2つの質問:

-OOPで純粋な関数を使用できますか?

-FPで関数をデータにバインドできますか?

両方の答えはイエスです。 静的なクラスメソッドは純粋であり、インスタンスメソッドでさえ副作用を引き起こさず、クラスインスタンスのプロパティをパラメーターと見なす場合はクリーンであると見なすことができます。 古典的な定義の境界線は膨らんでいて、意見の相違があるかもしれませんが、実際にはうまくいきます。 そして、そのような方法は、すべての規範に従って書かれた古典的な純粋な関数よりも悪くない形式でテストされています。 データへのメソッドのバインドについてはもう少し複雑です。使用する言語とライブラリには制限があります。 JavaScriptでは、これは基本的に行われ、HaskellとErlangについてはわかりません。 今、最も興味深いのは、それが与えるものと、OOPが20〜30年前にそのような誇大宣伝をすでに上げている理由です。 あなたが小さなプログラムを書く場合-あなたはあなたの美意識を除いてあなたが望むように書くことができます、それは何にも影響しません。 本当に大きなプログラムを作成すると、複雑さの問題が発生します。 計算の複雑さではなく、ここではすべてをうまく行っていると考えていますが、知覚された複雑さです。 50,000行のコードがあり、それらはすべて便利だとしましょう。 狂わないように(または11泊で仕事を辞めないように)整理する方法は? 操作の数を減らすことはできませんが、それらの間の接続の数を減らすことはできます(これはカプセル化に役立ちます)。 複雑な実装を単純なインターフェースの背後に隠し、インターフェースでのみ機能し続けます。 たとえば、インターネットは非常に複雑なものですが、ほとんどの開発者はHTTPプロトコルに関する十分な知識を持っており、仕事をして、ネットワーク、物理、その他のレベルをシステム管理者に任せています 。 モジュールの接続が弱いほど、相互の統合の段階での複雑さ軽減されます。 1つのモジュールが他のモジュールを認識しているほど、接続性は低下します。 モジュール内のデータにメソッドをバインドすると、モジュールのコンシューマーからこの知識を取り除くのに役立ちます。 これは、OOPの主な実用上の利点です。 何の上に? データとメソッドをバインドしない上記のアプローチ。 FPは、私たちが発見したように、これについては何も言っていません。 クラスを引数として純粋な関数に渡すことも、純粋な関数をクラスのメソッドとして使用することもできます。それは互いに矛盾せず、補足するだけです。



実際には、主に1つのアプローチが機能し、ほとんどの場合は別のアプローチが機能しますか? NodeJSでバックエンドを作成すると、それ自体が何らかの形で機能的なパラダイムになります。 なんで? サーバーへのリクエストは本来、固定の入出力を備えた機能であるためです。 機能的なアプローチはサーバー要求に非常に自然に当てはまり、コードはよりコンパクトで柔軟です。 ブラウザーのフロントエンドを作成すると、通常、 OOPの方がうまく機能します。これは、入出力に加えて、ユーザーイベントのストリームと、アニメーションの開始と終了、サーバーリクエストなどのプログラムイベントもあるためです。インタラクティブ機能なしで静的ページを描画するだけの場合、フロントエンドでFPを使用すると、インタラクティブまたは開発時間が低下します(測定によると、3回ごと)。 なんで?



プログラミングパラダイムは特定の現実モデルに基づいており、モデルは常に単純化されています。 FPでは、モデルにより世界により多くの制限が課されるため、形式化が容易になります。 同じ理由で、タスクの条件に関連しなくなると、より多くの松葉杖が必要になり始めます。 たとえば、フロントエンドFPは、イベント(アクション、redux hi)の配列を作成することにより、ユーザー入力の問題を解決しました。 ただし、これは無関係な抽象化であり、パフォーマンスへの影響に加えて、開発時間が大幅に増加します。 このアプローチを使用すると、todoリストを作成できますが、実際に大規模なプロジェクトでは、額でレンガを壊してから、同じ不幸な記事でも勝利の記事を書く必要があります。 比較のために、canvas、svgを使用して交換端末を(もちろんvanilla jsで)作成し、websocketを介して1秒間に数回更新しました。ブラウザーでの操作(これは、 非常に大きなアプリケーションがある場合に重要です )。 フロントエンドでプログラムを作成する場合、すべてのアクションがすべてのリデューサーを通過するという事実により、不変性(ところで、マルチスレッドで作業するための素晴らしいこと)に既に達しているため、そのような考えさえありません。およびその他のゴミ。 一方、バックエンドでは、タスクの条件がFPモデルに非常に関連しているため、クラスをまったく作成せずに済むため、クラスをまったく使用しないこともできます。 しかし、ほとんどの場合、JavaとPHPの開発者はFPを急ぐことなく、フロントエンドベンダーが最前線にいます。 心のためのエクササイズとして-もちろん興味深いのは、プログラムだけが取得されます...しかし、誰かがそれらを使用します。 フロントエンドは比較的若いIT部門であり、数世代にわたって未解決の問題がありますが。 心の運動ではないように思えますか?



All Articles