rgr*_*erg 9 continuations ocaml functional-programming delimited-continuations
我正在研究Oleg和Asai划定的"傻瓜"续篇(http://pllab.is.ocha.ac.jp/~asai/cw2011tutorial/main-e.pdf),但本文使用移位/重置形式而不是奥列格的delimcc提供的提示材料.所以我有几个问题:
首先,什么是提示?为什么传下来shift和其他功能?知道什么是subcont也不错,但我愿意跳过这个,因为我只是想通过论文.此外,它们之间的区别是什么shift,shift0以及它们shift在论文中的对应方式.
另外,什么是resetdelimcc?我的直觉告诉我,new_prompt并push_prompt以某种方式对应reset.但我在这里也需要澄清一些.
编辑:我能够从论文中翻译一个简单的例子,我的直觉证明是正确的.但是我想要对这些差异进行真正的解释,为什么delimcc就是这样的.这是两个版本,以防任何人感兴趣
纸:
reset (fun () -> 3 + shift (fun _ -> 5 * 2) - 1)
Run Code Online (Sandbox Code Playgroud)
Delimcc:
let _ = let open Delimcc in
let np = new_prompt () in
push_prompt np (fun () -> 3 + (shift np (fun _ -> 5 * 2)) - 1)
Run Code Online (Sandbox Code Playgroud)
gas*_*che 10
我建议你读的开始本文,这是奥列格演示的杂志版本delimcc.这将让您合理地理解delimcc这将使您将文章的shift/reset示例移植到delimcc多提示设置.
您可能感兴趣的两个引号.第一个是我上面提到的期刊版本:
已经熟悉分界控制的读者可以将delimcc视为普通移位/重置的概括,以控制任意多种"风味"的分隔符.该函数
new_prompt创建一个新的,独特的味道的控制分隔符 - 或提示符.表达式push_prompt p (fun () -> e)(泛化reset e)将控制分隔符p放在堆栈上然后进行求值e;take_subcont p f删除堆栈的前缀,直到标记为给定的最近堆栈帧p.堆栈的被移除部分(终止定界符p被切除)被打包为抽象类型子包的继续对象并传递给take_subcont参数f.该函数push_subcont将删除的堆栈帧放回堆栈,可能在不同的上下文中,从而恢复捕获的分隔连续.
第二个是GNU Guile的文档
还在?因此,当一个人实现分隔控制操作符时
call-with-prompt,需要做出两个决定.首先,处理程序是在提示符之内还是之外运行?让处理程序在提示符下运行允许处理程序内的中止返回到相同的提示处理程序,这通常很有用.但是它会阻止来自处理程序的尾调用,所以它不太通用.同样,调用捕获的延续会恢复提示吗?我们再次对便利与正确的尾调用进行权衡.
这些决定在Felleisen F运营商中捕获.如果continuation和处理程序都没有隐式添加提示,则运算符称为-F-.这是Guile
call-with-prompt和abort-to-prompt.的情况.如果continuation和handler都隐式添加提示,则运算符为+ F +.
shift并且reset是这样的运营商.
总结:你是正确的,要求new_prompt获得提示,然后push_prompt安装它是获得的方式reset.事实上,你只需要调用new_prompt一次,并且可以始终推送到同一个全局提示符,并获得通常shift/ reset行为(声明不同的提示只会给你更多的自由).
最后,shift可以用原语来定义delimcc,这就是在库中完成的.shift调用take_subcont,立即重新安装(相同)提示,并向用户提供将重新启动中止计算的函数.shift0做同样的事情,除了它没有重新安装提示.在delimcc代码中:
let shift p f = take_subcont p (fun sk () ->
push_prompt p (fun () -> (f (fun c ->
push_delim_subcont sk (fun () -> c)))))
let shift0 p f = take_subcont p (fun sk () ->
f (fun c -> push_delim_subcont sk (fun () -> c)))
Run Code Online (Sandbox Code Playgroud)