問題タブ [callcc]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
scheme - スキーム呼び出し/cc の問題 - exit の実装。
「コマンド」と「プログラム」のリストを再帰的に分析する必要があるプログラムを作成しています(これは、迷路に住むロボットのために教授によって発明された「ロボット言語」のインタープリターです)。私の最初の実装は遅すぎたため、call-with-current-continuation を使用することにしました。
call/cc がどのように機能するかは知っています。これとこれを説明として読みました。
私の call/cc はチュートリアルのこの部分に基づいています:
多くの場合、call-with-current-continuation を使用して、エスケープ プロシージャ以外の引数を取るプロシージャを呼び出します。たとえば、エスケープ手続き以外に 2 つの引数を取る手続きがあるとします。
(define (foo xy escape) ... (if (= x 0) (escape 'ERROR)) ...)) これは、手続きをカリー化して 1 引数の手続きにすることで修正できます。
[ 前の章でカリー化について議論すべきです! ]
x と y の値として 0 と 1 を渡し、foo にエスケープ プロシージャを渡したいとします。と言うより、
(call-with-current-continuation foo) foo への呼び出しに十分な引数を渡さない、
(call-with-current-continuation (lambda (escape) (foo 0 1 escape))) ラムダ式は、まさに私たちが望むことを行うクロージャを作成します。これは、引数 0、1、および call-with-current-continuation によって作成されたエスケープ プロシージャで foo を呼び出します。
ただし、何らかの理由で機能せず、次の例外がスローされます。
私の間違いを見つけて、なぜそれが起こるのかを説明してほしい...
この質問に関連するコードの部分は次のとおりです。
lisp - Common Lisp にプリミティブな「call-with-current-continuations」が存在しないのはなぜですか
Scheme はプリミティブなを提供しておりcall-with-current-continuation
、一般的に省略call/cc
されていますが、ANSI Common Lisp 仕様には同等のものはありません (ただし、それらを実装しようとするライブラリがいくつかあります)。
ANSI Common Lisp 仕様で同様のプリミティブを作成しないという決定が下された理由を知っている人はいますか?
ruby - Ruby における call/cc と「ensure」の意味
私がこれまでに知っているように、Ruby は(ブロックとして記述された)call/cc
との両方をサポートする唯一の主流言語です。try/catch/finally
begin/rescue/ensure/end
私はRubyに精通していませんが、直感的に、call/cc
任意の制御フローを許可しensure
、保証された制御フローを必要とするため、その2つの潜在的な競合があることを教えてくれます(一部のコードパスは、事前に定義された状況で実行する必要があります。ブロック)。
それで、言語に矛盾はありますか?もしそうなら、そのような場合の言語の定義された動作は何ですか? 特に、ブロックやブロックcall/cc
で使用されている場合はどうなりますか? ブロックの contains句の後にキャプチャを呼び出すとどうなりますか?begin/ensure
ensure/end
call/cc
ensure
lisp - 継続と関数の違いは何ですか?
継続は、次に何が起こるかを何らかの値で表しますよね?それは、値を取り、何らかの計算を行う単なる関数ではありませんか?
の続き(* 2 3)
は(+ _ 5)
call/cc
関数を使用せずにここで使用するポイントは何k
ですか?
haskell - HaskellでcallCCを解釈するには?
Scheme では、a から取得した継続を実行するcall/cc
と、その最初の呼び出し/cc に効果的にジャンプして戻り、保存された呼び出しスタックが復元されます。
Haskell の学習を始めたばかりで、理解する方法を理解しようとしていますcallCC
。それはcallCC
、Scheme の理解という観点から理解しようとすることcall/cc
です。の実装callCC
は
私が知る限り、保存または復元されたコール スタックに関しては何も言及されていません。SchemecallCC
のcall/cc
.
編集:誰かが以下をHaskellに翻訳できれば、理解に役立つでしょう。
haskell - callCC は厳密な関数型言語でどのように実装されていますか?
次の Haskell の関数の例quux
と、継続モナド および の定義を考えてみましょうcallCC
。
私がこの例を理解しているように。do ブロックは次のように考えることができます。
k
そして、 whichの定義から\a -> cont $ \_ -> h a
、上記では\x -> runCont ((\_ -> return 25) x) c
、アンダースコアで無視される引数に渡されていることがわかります。アンダースコア引数は決して使用されないため、最終的にreturn 25
は事実上「無視」されます。そのため、遅延評価から評価されることはありません。
callCC
したがって、この実装は基本的に遅延評価に強く依存していると言えます。callCC
厳密な (非遅延) 関数型言語でこれを行うにはどうすればよいでしょうか?
clojure - Clojure の core.async を「継続渡しスタイル」と表現できますか?
Clojure のcore.async ライブラリには、ブロックをラップしてブロック IO を処理するチャネルを作成するステート マシンを作成するマクロがあります。go
これは、 C#とGo-lang の goroutinesでモデリングし ているようです。async
The Seasoned Schemerでは、継続を渡すためのテクニックについて説明しています。(これは call/cc に基づいているようです)。また、Clojureの区切られた継続に関するDavid Nolenのライブラリも見られます。
ここでは、C#async
を「現在の継続を伴う呼び出し」と表現しています。
私の質問は、Clojure の core.async を「継続渡しスタイル」と記述できるかということです。
または、「継続」(区切られたものと区切られていないもの) はオーバーロードされた用語ですか?
編集: 追加の注意事項 - David Nolen は、core.async に対して wrt を言っています:
go ブロックの内部では、継続渡しスタイルでコードを手動で記述する必要がないように、これらのことを同期的に実行できるという錯覚を与えます。
scheme - call-with-current-continuation - 状態保存の概念
The Seasoned Schemerを読んだ後、私はcall/cc
きちんと理解できたと感じました。しかし、いくつかの WOW トリックを見た後、call/cc
私が間違っていることがわかりました。
それは私の理解と完全に一致します。call/cc
電話に出たとき、プログラムの状態を保存しているだけだと思います。関数でその隣の関数を呼び出します。その関数 ( k
) がどこかから呼び出された場合(call/cc ...)
、指定されたパラメーターで全体を置き換えるだけです。上記のプログラムもそのように機能したようです
しかし、
3 回呼び出すnext
と、0、1、および が生成され'done
ます。つまり、それによって与えられstate
た関数を使用すると、プログラムの状態が復元されませんでした。私はそれを理解しようとしたことをあなたに示しました。k
generator
call/cc
では、実際にはどのように機能するのでしょうか。