関数型プログラミング アーキテクチャ
-
01-07-2019 - |
質問
私は視覚化のためのデザインパターンやクラス図の使用など、オブジェクト指向アーキテクチャには精通しており、コントラクトやプロトコルバインディングを備えたサービス指向アーキテクチャについても知っていますが、 関数型プログラミング言語で書かれたシステムのソフトウェア アーキテクチャについて何か特徴はありますか?
FPは中規模から大規模なプロジェクトに使用されていると知っています。ポール・グレアムは Yahoo! の最初の化身を書きました。Common Lisp に保存します。一部の Lisp 開発システムは複雑です。関数型言語で書かれた人工知能と金融システムは、かなり大規模になる可能性があります。しかし、それらはすべて少なくともある種の固有のアーキテクチャを持っていますが、何か共通点があるのだろうか?
式の評価に基づくアーキテクチャはどのようなものでしょうか?FP アーキテクチャはより構成可能ですか?
アップデート: カイルが思い出させてくれた SICP は、このテーマに関する優れたリソースです。
更新 2: この件に関する良い投稿を見つけました。 関数型プログラミングはコードの構造にどのような影響を与えますか?
他のヒント
私は現在、「関数型プログラミングにおけるデザインとアーキテクチャ」という本を執筆中です。純粋な FP の世界 (主な言語は Haskell) に存在する多くの設計パターンとアプローチについて説明しますが、それだけではありません。この本では、純粋な状態と不純な状態、マルチスレッド、ネットワーク、データベース、GUI を使用して大きなアプリケーションを最初から構築する方法、それをレイヤーに分割してシンプルにする方法を説明します。また、ドメインと言語をモデル化する方法、アプリケーションのアーキテクチャを整理して説明する方法、テスト方法なども示します。
トピックのリストには次のものが含まれます。
- 図を使用したアーキテクチャ モデリングへのアプローチ。
- 要件分析;
- 組み込み DSL ドメイン モデリング。
- 外部 DSL の設計と実装。
- 効果を持つサブシステムとしてのモナド。
- 関数インターフェースとしての無料モナド。
- 矢印付きの eDSL;
- 無料のモナディック eDSL を使用した制御の反転。
- ソフトウェアトランザクションメモリ。
- レンズ;
- ステート、リーダー、ライター、RWS、ST モナド。
- 不純な状態:IORef、MVar、STM;
- マルチスレッドおよび同時ドメインモデリング。
- GUI;
- UML、SOLID、GRASP などの主流の技術とアプローチの適用可能性。
- 不純なサブシステムとの相互作用。
この本は、私が研究している Haskell プロジェクト、特に SCADA アプリケーションに基づいています。 アンドロメダ. 。この本のコードは利用可能です ここ. 。この本は開発中です (2017 年までに完成する予定です) が、私の記事「FP におけるデザインとアーキテクチャ」をよく読んでおくことをお勧めします。 ここ (ロシア)。
アップデート
私は自分の本をオンラインで共有しました(最初の 5 章)。 Reddit の投稿を参照
関数型言語で見られる最大の共通点は、関数を使用してデータを保存することです。これは、オブジェクトを持たずにオブジェクトに対してアクセサー関数を使用するのと少し似ています。代わりに、関数は、必要なデータにアクセスできる環境で作成されます。これで、この関数をどこにでも渡して使用できるようになり、データを使用する機能も保持されます。
非常に簡単な例を次に示します。これは状態を変更するため、純粋に機能的ではありませんが、十分に一般的です。
(define (make-counter)
(let ((count 0))
(lambda ()
(set! count (+ count 1))
count)))
(define x (make-counter))
(x) returns 1
(x) returns 2
...etc...
したがって、カウンターの状態を内部に持つ別の関数を返す関数 make-counter があります。新しく作成されたカウンターを呼び出して、内部の変化を観察できます。
これが関数型プログラムの構造です。関数を引数として受け取る関数や、非表示状態の関数を返す関数などがあります。自分でメモリを管理するよりもはるかにクリーンです。
私はいくつかのかなり大規模な機能プロジェクトに取り組んできました。通常、これらは 2 つの陣営に分類されます (少なくとも、私が使用した陣営)。
- 優れたスケーラビリティ/信頼性/同時実行性。トランザクション モデルは言語に非常に緊密に組み込むことができます。Concurrent ML はその良い例であり、これを使用するプロジェクトは、同時実行性の正確さに関しては非常に間違うことがありません。
- フレームワークの解析/変更。これらのフレームワークのベースとなる設計パターンの多くは、関数型言語で定式化/構築/変更することが非常に簡単です。訪問者のパターンはその好例です。
プリントアウトして見てみました Ocaml のデザインパターン, そして、モジュールとファンクター (およびオブジェクト) を使用して、私たちが慣れ親しんでいる通常のデザイン パターンを再作成します。面白いけど、物を使っている気がする あまりにも 関数型言語の利点を実際に理解するのは非常に簡単です。FP はその性質の一部として、非常に構成可能です。私の簡単な答えは、使用することだと思います モジュール そして ファンクター.
私の現在のプロジェクトはかなり大きく、ocaml の --implicit ファイルで各モジュールを分割しています。私は、プロジェクトから生まれた本当に成功したデザインについての別の視点や考えが載っている包括的なリソースも探しています。
あまり関係のないことを願っていますが、この質問に対する答えを閲覧している人にとっておそらく興味深いのは、このプレゼンテーションです。 動的プログラミングにおけるデザインパターン ピーター・ノーヴィグ著。
これが役立つかもしれないと思います。
一部のパターンは消えます。つまり、言語の特徴によって直接サポートされており、一部のパターンはより単純であるか、焦点が異なり、本質的に変更されていません。
[AIM-2002-005] グレゴリー T.サリバン 実行可能なデザインパターンのための高度なプログラミング言語機能「リフレクションによるより良いパターン」
2002 年 3 月 22 日
Design Patterns Book [GOF95]は、適切に設計されたソフトウェアシステムに一貫して表示される24の実施されたパターンを示しています。各パターンには、パターンが扱う設計問題の説明と、サンプルの実装コードと設計上の考慮事項が表示されます。このペーパーでは、「ギャングオブフォー」、または「GOF」の本からのパターンが、しばしば呼ばれるように、動的で高次のオブジェクト指向のプログラミング言語を使用して同様の問題に対処されたときにどのように表示されるかを探ります。一部のパターンは消えます。つまり、言語の特徴によって直接サポートされており、一部のパターンはより単純であるか、焦点が異なり、本質的に変更されていません。