callcc 㨠shift/reset ã«ã¤ãã¦ãããã¨ãã ãæ¸ãã¦ã¿ã¾ãã
ç¶ç¶
callcc ã¨ããæä½ã¯ãç¾å¨ããå®è¡çµäºã¾ã§ãç¶ç¶ãã¾ããã¨åãåºãã¾ããä¾é¡ã
p [1] + callcc {|k| [2] + k.call([3]) } #=> [1, 3]
callcc ã§ã¯ callcc ããªã¿ã¼ã³ãã¦ããå®è¡çµäºããã¾ã§ã®ç¶ç¶ k ãåãåºãã¾ããk.call([3]) ã§ç¶ç¶ãå¼ã°ããã¨ããããªããcallcc ã [3] ãè¿ããç¬éãã«å®è¡ãé£ã³ã¾ããã¤ã¾ããããªæãã
p [1] + [3]
ãã¨ã¯èªæã§ããã"[2] +" ã®ãããã¯ç¡è¦ããã¾ãã
é¨åç¶ç¶
shift ã¨ããæä½ã¯ãç¾å¨ãã reset ã¾ã§ãç¶ç¶ã®ä¸é¨ã ããåãåºãã¾ãããã®ç¶ç¶ã®ä¸é¨ãé¨åç¶ç¶ã¨ããã¾ããä¾é¡ã
p [1] + reset { [2] + shift {|k| [3] + k.call([4]) } } #=> [1, 3, 2, 4]
shift ã§ã¯ shift ããªã¿ã¼ã³ãã¦ãã reset ã«å°éããã¾ã§ã®é¨åç¶ç¶ k ãåãåºãã¾ããk.call([4]) ã§é¨åç¶ç¶ãå¼ã°ããã¨ããããªããshift ã [4] ãè¿ããç¬éãã«å®è¡ãé£ã³ã¾ããcallcc ã¨åãã§ããã
p [1] + reset { [2] + [4] }
ãã㦠reset ã®ãããã¯ã¯ [2, 4] ãè¿ãã¦çµããã¾ããããã¨ä»åº¦ã¯ãããªããk.call ã [2, 4] ãè¿ããç¬éãã«å®è¡ãé£ã³ã¾ããåéã£ã¦æãã
p [1] + reset { [2] + shift {|k| [3] + [2, 4] } }
shift ã®ãããã¯ã¯ [3, 2, 4] ãè¿ãã¦çµããã¾ããä»åº¦ã¯ã¾ããããªããreset ã [3, 2, 4] ãè¿ããç¬éãã«å®è¡ãé£ã³ã¾ããé£ã³ã¾ããã§ããã
p [1] + [3, 2, 4]
ãã¨ã¯ãã®ã¾ã¾ã
ãããããä¾
reset ã®ä¸ã§è¤æ°å shift ããã¨ãããããã§ãããåºæ¬ã¯åãã§ãã
x = [1] + reset do shift {|k| [2] + k.call([3]) } + shift {|k| [4] + k.call([5]) } + [6] end p x #=> [1, 2, 4, 3, 5, 6]
k.call([3]) ãå¼ã°ããã
x = [1] + reset do [3] + shift {|k| [4] + k.call([5]) } + [6] end p x
k.call([5]) ãå¼ã°ããã
x = [1] + reset do [3] + [5] + [6] end p x
[3, 5, 6] ã reset ããããå¾ã« shift ããæ¹ããé ã«åéãã¦ããæããããã§ã¯ k.call([5]) ã¸ã
x = [1] + reset do shift {|k| [2] + k.call([3]) } + shift {|k| [4] + [3, 5, 6] } + [6] end p x
å¾åã® shift ã®ãããã¯ã [4, 3, 5, 6] ãè¿ãã¦çµããã®ã§ reset ã«é£ã¶ãã©ãã¾ã shift ãæ®ã£ã¦ããã®ã§ãã£ã¡ã«é£ã¶ã
x = [1] + reset do shift {|k| [2] + [4, 3, 5, 6] } + shift {|k| [4] + k.call([5]) } + [6] end p x
ååã® shift ã®ãããã¯ã [2, 4, 3, 5, 6] ãè¿ãã¦çµããã®ã§ reset ã«é£ã¶ããã shift ã¯æ®ã£ã¦ãªãã®ã§ãã®ã¾ã¾ reset ãçµããã
x = [1] + [2, 4, 3, 5, 6] p x
èå¯
ãªãã ãé£ã³ã¾ããã§ãããããã§ãããè¦ã¯é¨åç¶ç¶ã®å¼ã³åºã k.call ã¯ã試ãã« shift ããªã¿ã¼ã³ããã¦ãreset ã«å°éããã¾ã§å®è¡ãã¦ããã®è¿ãå¤ãæã£ã¦ãããã ãã§ãã
ã¾ããä¸ã®æåã®ä¾ã§ã¯å®ã¯é¨åç¶ç¶ k 㯠proc {|arg| [2] + arg } ã¨åãã§ããã¤ã¾ããreset ã®ãããã¯ã¯ 1 å¼æ°ã®ã¯ãã¼ã¸ã£ã§ãããshift ã®å¼ã³åºãããã®å¼æ°ã«ç½®ãæãã£ã¦ãããã¨è¦ããã¨ãã§ãã¾ãã
以ä¸ãContinuation Fest ã«è¡ããªãã£ãã®ã§ããªãããã ãã æ¸ãã¦ã¿ã¾ããããªããééã£ã¦ããæãã¦ãã ããã
ãã¾ã
Ruby ã§ã® shift/reset ã®å®è£ ã1.9 ç¨ãã¹ã¬ããã¨ãã¯èããªãã
require "continuation" def shift callcc {|c1| $ctn.(yield(proc {|v| callcc {|c2| $ctn = c2; c1.(v) } })) } end def reset callcc {|c| $ctn = c; v = yield; $ctn.(v) } end