web-dev-qa-db-ja.com

Clojureには継続/コルーチンなどがありますか?

私はPythonでプログラミングを始めましたが、コルーチンやクロージャーなどの概念に本当に戸惑いました。

今、私はそれらを表面的なレベルで知っていると思いますが、その「悟り」の瞬間を感じたことがないので、私はClojureを学ぶことにしました。スチュアートハロウェイの本を購入して良かったのですが、索引を見るとコルーチンや継続のような言葉はありませんでした。私はそれらをググったが、そこにも何もない。

だから、私の質問は:

Clojureには、スタックオーバーフローなしでping-pongingなどのタスクを実行するための継続またはコルーチンがありますか?

Pythonの例(ただし、標準Pythonは、この対称コルーチンのフル機能バージョンをサポートしていません):

def ping():
  while 1:
   print "ping"
   function to switching to pong

def pong():
  while 1:
   function to switching to ping
   print "pong"
20
Novice

Clojureにはcall/ccはありませんが、 区切りなしの継続は必要ありません とにかく。

他のすべてをネイティブにライブラリーに委任するために実装する際立った制御操作として、コア言語機能としてのcall/ccに反対します。プリミティブcall/ccは、悪い抽象化です-以下に示す '悪い'のさまざまな意味で-そして、その継続のキャプチャプログラム全体は実用的ではありません。継続全体を効率的にキャプチャするためのハードワークに対する唯一の報酬は、継続全体のキャプチャを回避するためのよりハードなワークです。ユーザーと実装者の両方が、よく考えられた相互作用を備えた、さまざまな程度の一般性を持つ適切に選択された一連の制御プリミティブを提供する方が適切です...

...他のすべての制御機能を実装する必要があるという点で、コア制御機能としてcall/ccを提供することは悪い考えです。パフォーマンス、メモリ、リソースのリーク、実装の容易さ、使いやすさ、推論の容易さはすべてcall/ccに反対しています。プリミティブとして実装する明確な制御機能が実際に1つあり、他の機能がライブラリに委任されている場合、それはcall/ccではありません。

David NolenがClojure用に 区切り付き継続ライブラリ を作成しました。やってみよう!

delimc

Clojure 1.4.0(および1.3.0)の区切り付き継続ライブラリ。 Slava Akhmechetによるcl-contに基づく部分( http://defmacro.org )...

20
Frank Shearar

Clojureには、コア機能として組み込みのファーストクラスの継続またはコルーチンはありませんが、独自のものを実装することは可能です。

たとえば、 core.async は、CSP(並行順次プロセス)モデルを実装するClojureライブラリです。 goマクロを使用して、内部のコードをステートマシンに変換します。コルーチン自体は正確ではありませんが、同じパターンを実装するために使用できます。

pulley.cps もあります。これは、私が作成したマクロコンパイラであり、(cps/cps-fnマクロを介して)直接スタイルで継続渡しスタイルに記述されたClojureコードを変換します。私の知る限り、これは継続をテーマにした最も完全なClojureプログラムです。動的バインディング、例外、ネイティブコードと変換されたコード間のやり取りをサポートします(ただし、継続はコンテキスト間で維持されません)。現時点では、中断された継続(つまり、従来のcall-cc)のみがサポートされていますが、将来は区切り付き継続を実装する計画があります。

Pulley.cpsはコルーチン自体を直接提供しませんが、call-ccを使用すると、独自のコルーチンを実装するのが比較的簡単です。実際、例の1つは cooperative multitasking の単純な実装です。これは [〜#〜] csp [〜#〜] の例でさらに構築されています。 Ping-Pong の例もありますが、コルーチンよりも末尾呼び出しの最適化の例です。

もちろん、この種の変換は、プログラム全体に適用すると最も効果的です。残念ながら、これはローカライズされたマクロだけでは不可能です。それでも、ローカライズされた変換でさえ非常に効果的です。

2
Nathan Davis

Clojureには、スタックオーバーフローなしでping-pongingなどのタスクを実行するための継続またはコルーチンがありますか?

古い質問なので、この機能が当時利用可能であったかどうかさえわかりませんが、「ピンポン」機能を実装したい人は、trampoline

Clojureでの効率的な継続渡しスタイルに関する私の質問への回答としてそれを発見しました、ここ: https://stackoverflow.com/questions/50952443/continuation-passing-style-does-not-seem-to -make-a-difference-in-clojure/50955276#50955276 そして、それは単なる仕事だと思います。少し前に聞いたことがありますが、完全には調査していません。もっと私をだます。他の多くの提案されたソリューションとは異なり、それは機能します

====== PS。オンラインの大量のチュートリアル情報]は、ここにいくつかの便利な情報があります。

1
alex gian