kakiの最近の限定継続いじり

個人的な活動のまとめ 関連記事: Racketの継続プリミティヴ - かきにっき http://d.hatena.ne.jp/gengar/20140406/1396795808 ここで分かったことのまとめ
4
kaki @gengar68

shift/resetの動的な性質が前から気持ち悪いと思ってたんだけど,これreset式が継続デリミタオブジェクトみたいなのを作って明示的にshiftに渡すんじゃ駄目なのかな.

2014-03-06 15:22:14
kaki @gengar68

さっき書いたやつ,shift-at/reset-atで実装できそうだなぁ.

2014-03-06 16:27:47
kaki @gengar68

(define-syntax reset* (syntax-rules () ((_ t body0 body ...) (let ((t (make-continuation-prompt-tag))) (reset-at t body0 body ...)))))

2014-03-06 16:36:09
kaki @gengar68

shift0 は限定継続を切り取る時に,その reset0 をも取り除くのかな.

2014-03-06 16:08:55
kaki @gengar68

(+ 20 (reset (+ 1 (shift _k (shift k (k (k 2))))))) では外側の shift で (+ 1 <>) だけ切り取られるから k はなにもせず内側の shift から 2 が reset の外に返ってきて結果は 22 に.

2014-03-06 16:09:40
kaki @gengar68

一方 (reset0 (+ 20 (reset0 (+ 1 (shift0 _k (shift0 k (k (k 2)))))))) では外側の shift0 で (+ 1 <>) が切り取られると同時に内側の reset0 がなくなって,k は (+ 20 <>) に.

2014-03-06 16:10:16
kaki @gengar68

で shift0 の結果は 42 になり,それがそのまま外側の reset0 の結果になる.reset0 が除去される分,shift と比べて一つ余分に reset0 が必要になる.ってことでいいのかな.

2014-03-06 16:11:05
kaki @gengar68

racketのトップレベルはREPL同様 #<void> 以外の結果を返すと print するのか.plt-r5rsでもなんか表示された.plt-r6rsでは表示されない.

2014-03-10 14:56:22
kaki @gengar68

限定継続っていろいろバリエーションがあるけど,shift/resetがいいってことなんだろうか.

2014-03-08 21:52:50
kaki @gengar68

あ,わかった.control があれば shift はすぐ書けるってことか. QT @stibear1996: gengar68 https://t.co/QLWVIST2g1 こういってる人もいます

2014-03-08 22:39:05
kaki @gengar68

こうなると当然次の疑問は,prompt/controlが限定継続のプリミティヴな演算子なのかどうか,ということなのだが,そろそろ実装すればいろいろ分かる気がしてきた.というか,実装できそうな気がなんとなくしてきた.根拠はないがそんな気分になった.

2014-03-09 02:07:21
kaki @gengar68

いきなり shift した時の挙動からトップレベルに暗黙の reset が入っていると思うのだけど,いきなり shift0 するとそこで終了してしまう.reset と reset0 は同じものっぽいし reset 入れると同じ挙動になるのだけど…あまり考えない方がいいのかなぁ.

2014-03-10 15:04:21
でこれき @dico_leque

Racket だとトップレベルに (default-continuaiton-prompt-tag) がついているので、resetなしでshiftするとそこまでの継続が取り出されるのかな。ただし、取り出した継続の末尾にexit相当のものがあるので呼び出した継続は返ってこない

2014-03-15 16:14:35
でこれき @dico_leque

いきなり shift0 すると終了するのは、トップレベルまで abort/cc したところで終了するのかな

2014-03-15 16:37:35
kaki @gengar68

うおう,なんかRacketで prompt と control で無限ループを引き起こしたのでC-cしたら,#<void> が返ってきて実行が継続された.(abort (void)) 的なことになっているのだろうか.

2014-03-10 18:30:20
kaki @gengar68

無限ループの中で prompt 積み立ててたらどうなるのか気になる(やらない)

2014-03-10 18:30:51
kaki @gengar68

(prompt (control k (k (k 0))) (control k (k (k 1))))

2014-03-10 18:34:01
kaki @gengar68

(let ((k0 #f)) (prompt (control k (set! k0 k)) (control k (k (k 0)))) (prompt (+ 1 (k0)))) うーんなるほど,これを考えると reset を仕込む shift が自然な気がしてくる.

2014-03-10 20:12:34
kaki @gengar68

Scalaのshift/resetでは,shift で切り出す継続の型を明示することになるのか.これに多相性を持たせるには…?あれ,そもそもScalaって関数オブジェクトはパラメタ多相性持てないんだっけ?

2014-03-11 17:06:30
kaki @gengar68

こういうことはできた.これがやりたかったことなのかはよく分からない. scala> def f[A]() = reset { shift { k: (A => A) => k }} f: [A]()A => A scala> f()(42) res20: Int = 42

2014-03-11 17:11:37
kaki @gengar68

call/cc も reset で区切れるんだよね. ((reset (call/cc (lambda (k) k))) 42) ; => 42

2014-03-11 23:33:21
でこれき @dico_leque

Racket だと call/cc は直近の prompt tag までの継続を捕捉するという定義になっている http://t.co/tD9tIgiduW

2014-03-11 23:37:48
kaki @gengar68

と思ったけどこれはRacketの話で,Gaucheだとattempt to return from a ghost continuationだった.Gaucheでは混ぜて使えないのかな.

2014-03-11 23:39:38