The best days are ahead of us.

純粋な相互作用

2025-04-08 14:00:25

原文: Pure interactions by Mark Seemann

実行時間が長く、非決定的な相互作用も、純粋かつ関数的なアプローチでモデル化することが可能です。

以前の記事で、なぜ依存関係の注入(DI)と(厳密な意味での)関数型プログラミングが互いに相容れないのかを解説しました。 依存関係の注入はあらゆるものを不純にしてしまい、もし純粋なものが何もなければ、それは関数型プログラミングとは言い難いでしょう。 また、依存関係の排除という記事では、不純なコードと純粋なコードを分離し、不純/純粋/不純のサンドイッチ構造にする方法をしばしば見ることができます。

マイクロオペレーションベースのアーキテクチャ

不純/純粋/不純のサンドイッチアーキテクチャは、相互作用が限定的なシナリオにおいてはうまく機能します。 システム境界にデータが到着し、システムが応答する、ただそれだけです。 しかし、これは今日世界で稼働しているソフトウェアのかなりの部分に当てはまります。

HTTPベースのアプリケーション(Webサイト、REST API、ほとんどのSOAPサービスなど)はこの説明に合致します。つまり、HTTPリクエストが到着し、サーバーがHTTPレスポンスを返すという流れです。 適切に設計され、順調に稼働しているシステムであれば、レスポンスは数秒以内、あるいはそれよりも速く返されるべきです。 ソフトウェアが処理を完了するために必要な情報はすべて、リクエスト自体に含まれているか、アプリケーションの状態として保持されています。 受信したリクエストに基づいて追加データを収集するためにデータベースに問い合わせる必要があったとしても、不純なソースから必要なデータの大部分を収集し、それらをまとめて純粋なコア実装に渡し、純粋な結果を受け取ってからレスポンスを返す、という処理は可能です。

同様に、pub/sub、パイプ&フィルター、アクターモデル、いわゆる「正しく実装されたSOA」、CQRS/イベントソーシングといった非同期メッセージベースのシステムも、短時間で完結するステートレスな相互作用に基づいています。 HTTPベースのアプリケーションと同様、多くの場合(永続化された)アプリケーション状態が存在しますが、メッセージがハンドラに到着したら、ソフトウェアはそれを可能な限り迅速に処理すべきです。 この場合も、データベースから追加の(不純な)データを読み込み、すべてを純粋な関数に渡して処理し、最終的にその戻り値を使って何か不純な操作を行うことができます。

これらのシステムすべてに共通するのは、大量のデータを扱える一方で、それは多数の並列かつ独立した、分離されたマイクロオペレーションの積み重ねの結果であるという点です。

インタラクション型ソフトウェア

しかし、ソフトウェアには別のカテゴリも存在します。これを「インタラクション型ソフトウェア」と呼びましょう。 その名の通り、これにはユーザーインターフェースを持つソフトウェアすべてが含まれますが、長時間実行されるバッチジョブや、以前の記事で見たような時間的制約のあるソフトウェアなども該当します。

このようなソフトウェアでは、不純/純粋/不純のサンドイッチアーキテクチャを適用することはもはや不可能です。 例えば、電子メールクライアントのようなUIベースのプログラムを考えてみましょう。 メールを作成して送信し、返信を受け取り、また返信を作成する、といった一連の操作を行います。 送受信のたびに不純な処理が発生し、ユーザーインターフェースの描画もすべて不純な操作です。 次に何が起こるかはそれまでの操作に依存し、現実世界で起こることはすべて不純です。

私たちはついに、関数型プログラミングの限界に行き当たったのでしょうか?

そんなことはありません。 この一連の記事では、純粋な相互作用をモデル化する方法を解説していきます:

F# に関する記事だけを読みたい場合は、Haskellの記事は読み飛ばしても構いません。

この一連の記事を通じて、F# における純粋な相互作用とフリーモナドについて、包括的に理解を深めることができます。 動機付けとなる具体例としては、Pure timesを参照してください。こちらはより現実的な例を示していますが、詳細レベルは本シリーズほどではありません。

まとめ

継続的に発生する不純な相互作用という問題に対する解決策は、それらを(ドメイン固有の)抽象構文木(AST)における命令としてモデル化し、その純粋なASTを解釈・実行する不純なインタプリタを用いることです。 要求される構文を扱いやすくするために、ASTを(フリー)モナドとしてモデル化することができます。

次: 純粋なコマンドラインインタラクション入門


インデックスへ戻る