web-dev-qa-db-ja.com

ファーストクラスの継続は、最新のオブジェクト指向プログラミング言語で役立ちますか?

継続は、関数型プログラミング言語(HaskellのContモナドなど)で非常に便利です。命令型スタイルのコードに対して、単純で規則的な表記が可能だからです。また、不足している言語機能(例外、コルーチン、グリーンスレッドなど)を実装するために使用できるため、一部の古い命令型言語でも役立ちます。ただし、これらの機能のサポートが組み込まれた最新のオブジェクト指向言語の場合、ファーストクラスの継続のサポートを追加するためにどのような引数がありますか(よりモダンな区切りスタイルresetおよびshiftまたはスキーマのようなcall-with-current-continuation)?

引数はありますかagainstパフォーマンスと実装の複雑さ以外のサポートを追加していますか?

10
Jules

Eric Lippertにこれを答えさせましょう:

この時点で明らかな問題は、CPSが非常に優れている場合は、なぜそれを常に使用しないのかということです。ほとんどのプロの開発者がそれについて聞いたことがないのはなぜですか?または、それを持っている人は、クレイジーなSchemeプログラマーだけが行うことと考えているのですか?

まず第一に、サブルーチン、ループ、try-catch-finallyなどを考えることに慣れているほとんどの人にとって、デリゲートがこのように制御フローに使用されていることを推論することは簡単ではありません。私は今、CS442からのCPSに関するメモを確認しています。1995年にprofQUOTEを書き留めたことがわかりました。「継続する場合は、頭の上に立って自分を裏返しにする必要があります」。ダガン教授(*)は、そう言ったのは間違いなく正しい。数日前から、C#式M(B()?C():D())のCPS変換の小さな例に4つのラムダが含まれていたことを思い出してください。誰もが高階関数を使用するコードを読むのが得意というわけではありません。それは大きな認知的負担を課します。

さらに、特定の制御フローステートメントを言語に焼き付けることの良い点の1つは、メカニズムによって、呼び出しフロー、戻りアドレス、例外ハンドラーリスト、保護された領域を隠しながら、コードで制御フローの意味を明確に表現できることです。等々。 継続により、制御フローのメカニズムがコードの構造で明示的になります。メカニズムに重点を置いているすべてコードの意味を圧倒する可能性があります。

次の記事 では、非同期性と継続性が互いにまったく同等である方法を説明し、単純な(ただしブロックしている)同期ネットワーク操作を取り、それを非同期スタイルで書き換えるデモンストレーションについて説明します。それを正しくするためにカバーされなければならないすべての隠された問題を確実にカバーすること。それはコードの大量の混乱に変わります。最後の彼の要約:

神聖な善、私たちが作ったなんてひどい混乱です。完全に明確な2行のコードを、これまでにない最もゴージャスなスパゲッティの20行に拡張しました。そしてもちろん、ラベルも対象範囲外であり、明確な割り当てエラーがあるため、コンパイルもできません。これらの問題を解決するには、コードをさらに書き直す必要があります。

CPSの長所と短所について私が言っていたことを覚えていますか?

  • PRO:単純なパーツから任意に複雑で興味深い制御フローを構築できます–チェックしてください。
  • CON:継続による制御フローの具体化は、読みにくく、推論も困難です–チェック。
  • CON:制御フローのメカニズムを表すコードは、コードの意味を完全に覆します–チェック。
  • CON:通常のコード制御フローからCPSへの変換は、コンパイラーが得意で、他の誰も得意としないものです–チェックしてください。

これは知的運動ではありません。実際の人々は、非同期に対処するとき、常に上記と道徳的に同等のコードを作成することになります。そして、皮肉なことに、プロセッサが高速で安価になったとしても、私たちはますます多くの時間を費やしています。 プロセッサーにバインドされていないものを待機しています。多くのプログラムでは、ネットワークパケットがイングランドから日本と戻って、またはディスクを回転させるために、または何でも。

さらに、非同期操作をさらに構成したい場合に何が起こるかについても触れていません。 ArchiveDocumentsをデリゲートをとる非同期操作にしたいとします。これを呼び出すすべてのコードもCPSで記述する必要があります。汚れが広がるだけです。

非同期ロジックを正しくすることは重要であり、将来的にはさらに重要になるだけですと私たちがあなたに提供したツールは、「頭の上に立って自分を裏返しにする」ダガン教授が賢明に言ったように。

はい、継続渡しのスタイルは強力ですが、その能力を上手に活用するには、上記のコードよりも優れた方法が必要です。

両方の記事、および 次のシリーズ は、このすべての混乱をコンパイラーに移動し、特定の部分を非同期としてマークする特別なキーワードを使用して通常の制御フローとしてコードを記述できる新しいC#言語機能についてです。 C#開発者でなくても、読む価値があります。私はそうではありませんが、それを初めて遭遇したとき、それはまだかなり啓発的な経験でした。

15
Mason Wheeler