私はほとんどC / C ++プログラマーです。つまり、私の経験の大部分は手続き型およびオブジェクト指向のパラダイムに関するものです。ただし、多くのC ++プログラマーが認識しているように、C ++は長年にわたって機能的なスタイルに重点を移しており、最終的にC ++ 0xにラムダとクロージャーが追加されました。
とにかく、C ++を使用した関数型スタイルでのコーディングの経験はかなりありますが、LispやHaskellなどの実際の関数型言語の経験はほとんどありません。
私は最近、これらの言語の研究を始めました。なぜなら、特に並行性と分散コンピューティングへの応用に関して、純粋に機能的な言語の「副作用なし」という考えが常に興味をそそっていました。
ただし、C ++のバックグラウンドから来ると、この「副作用なし」の哲学が非同期プログラミングでどのように機能するかについて混乱しています。非同期プログラミングとは、ユーザーが提供するイベントハンドラーをディスパッチして、非同期に発生するイベントを処理するフレームワーク/ API /コーディングスタイルを意味します(プログラムのフロー外)。これには、Boost.ASIOなどの非同期ライブラリ、または単なる古いCさえ含まれます。シグナルハンドラまたはJava GUIイベントハンドラ。
これらすべてに共通することの1つは、非同期イベントハンドラーが呼び出されたことをプログラムのメインフローが認識するために、非同期プログラミングの性質が副作用(状態)の作成を必要とするように見えることです。通常、Boost.ASIOのようなフレームワークでは、イベントハンドラーはオブジェクトの状態を変更するため、イベントの効果はイベントハンドラー関数の有効期間を超えて伝播されます。本当に、イベントハンドラは他に何ができますか?コールポイントがないため、コールポイントに値を「返す」ことはできません。イベントハンドラはプログラムのメインフローの一部ではないため、実際のプログラムに影響を与える唯一の方法は、状態を変更することです(またはlongjmp
、別の実行ポイントに変更することです)。
そのため、非同期プログラミングは、副作用を非同期的に生成することがすべてのようです。これは、関数型プログラミングの目標と完全に矛盾しているようです。これら2つのパラダイムは、関数型言語でどのように(実際に)調整されますか?