我正在研究Oleg和Asai的定界延续“傻瓜”论文(http://pllab.is.ocha.ac.jp/~asai/cw2011tutorial/main-e.pdf),但是本文改用shift/reset形式主义Oleg的delimcc中提供的一些即时提示。所以我有几个问题:
首先,提示是什么?以及为什么在shift
和其他函数中传递?知道什么是subcont也很好,但是我愿意跳过这一点,因为我只想阅读本文。此外,本文中的shift
和shift0
之间有什么区别以及它们与shift
的对应关系如何。
另外,derimcc中的reset
是什么?我的直觉告诉我new_prompt
和push_prompt
在某种程度上与reset
相对应。但我在这里也需要澄清。
编辑:我能够从论文中翻译一个简单的例子,我的直觉就正确了。但是,我想对差异做一个真正的解释,为什么它们是delimcc的。这是两个版本,以防有人感兴趣
纸:
reset (fun () -> 3 + shift (fun _ -> 5 * 2) - 1)
Delimcc:
let _ = let open Delimcc in
let np = new_prompt () in
push_prompt np (fun () -> 3 + (shift np (fun _ -> 5 * 2)) - 1)
最佳答案
我建议您阅读this paper的开头,它是Oleg的delimcc
演示文稿的日记版本。这将使您对delimcc
有一个合理的了解,从而使您可以将文章的移位/重置示例移植到delimcc
的多提示设置。
您可能会感兴趣的两句话。首先是我上面指出的期刊版本:
The reader already familiar with delimited control may view delimcc as a generalization of the ordinary shift/reset to control delimiters of arbitrarily many ‘flavors’. The function
new_prompt
creates a control delimiter – or prompt – of a new, unique flavor. The expressionpush_prompt p (fun () -> e)
, the generalization ofreset e
, puts the control delimiterp
on the stack and then evaluatese
;take_subcont p f
removes the prefix of the stack up to the closest stack frame marked with the givenp
. The removed portion of the stack, with the terminating delimiterp
cut off, is packaged as a continuation object of the abstract type subcont and passed totake_subcont
’s argumentf
. The functionpush_subcont
puts the removed stack frames back on the stack, possibly in a different context, thus reinstating the captured delimited continuation.
第二个来自GNU Guile's documentation
Still here? So, when one implements a delimited control operator like
call-with-prompt
, one needs to make two decisions. Firstly, does the handler run within or outside the prompt? Having the handler run within the prompt allows an abort inside the handler to return to the same prompt handler, which is often useful. However it prevents tail calls from the handler, so it is less general.Similarly, does invoking a captured continuation reinstate a prompt? Again we have the tradeoff of convenience versus proper tail calls.
These decisions are captured in the Felleisen F operator. If neither the continuations nor the handlers implicitly add a prompt, the operator is known as –F–. This is the case for Guile's
call-with-prompt
andabort-to-prompt
.If both continuation and handler implicitly add prompts, then the operator is +F+.
shift
andreset
are such operators.
结论:您是正确的,调用
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)))
关于functional-programming - 如何将移位/重置转换为delimcc?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14431257/