我在某处读到Rich Hickey说:
"我认为延续理论上可能很好,但在实践中并不如此"
我不熟悉Clojure。
1. Clojure是否有延续?
2. 如果没有,你不需要延续吗?我看过很多很好的例子,特别是来自这位。有什么替代方案吗?
3. 如果有,是否有相关文档?
我在某处读到Rich Hickey说:
"我认为延续理论上可能很好,但在实践中并不如此"
我不熟悉Clojure。
1. Clojure是否有延续?
2. 如果没有,你不需要延续吗?我看过很多很好的例子,特别是来自这位。有什么替代方案吗?
3. 如果有,是否有相关文档?
在讨论continuations时,你需要区分两种不同的continuation:
第一类continuation - 深度整合到语言中的continuation支持(Scheme或Ruby)。Clojure不支持第一类continuation。
传递continuation风格(CPS)- CPS只是一种编码风格,任何支持匿名函数的语言都可以允许这种风格(也适用于Clojure)。
例子:
-- Standard function
double :: Int -> Int
double x = 2 * x
-- CPS-function – We pass the continuation explicitly
doubleCPS :: Int -> (Int -> res) -> res
doubleCPS x cont = cont (2 * x)
; Call
print (double 2)
; Call CPS: Continue execution with specified anonymous function
double 2 (\res -> print res)
我认为continuations并不是一门好语言所必需的,但是在函数式语言如Haskell中拥有一级continuations和CPS可以非常有用(智能回溯示例)。
我编写了一个Clojure版本的cl-cont,它为Common Lisp添加了continuations。
延续是一种抽象概念,用于描述控制流语义。在这个意义上,它们存在也不存在(记住,它们是抽象的),在任何提供控制运算符的语言中都是如此(因为任何图灵完备的语言必须如此),就像数字既存在(作为抽象实体)又不存在(作为有形实体)。
延续描述了诸如函数调用/返回、异常处理甚至goto之类的控制效果。一个良好的语言将会在许多方面上设计基于延续的抽象(例如异常)。 (也就是说,一个良好的语言将包含考虑到延续而设计的控制运算符。当然,让语言仅暴露延续作为唯一的控制抽象,允许用户在其之上构建自己的抽象,这也是完全合理的。)
虽然一级续体在许多情况下是一个强大而有用的工具,但在语言中暴露它们也存在一些缺点:
finally
块。通过元编程,可以将对一级继续的支持添加到语言中。 通常,此方法涉及将代码转换为传递风格(CPS),其中当前继续作为显式参数传递给每个函数。
例如,David Nolen的delimc库通过一系列宏转换实现了Clojure程序部分限定续延。类似地,我编写了pulley.cps,这是一个宏编译器,将代码转换为CPS,并提供运行时库以支持更多核心Clojure功能(如异常处理)以及与本地Clojure代码的互操作。语言中是否需要“continuation”这一特性?
不需要。许多语言没有“continuation”的概念。
如果不需要,那你不需要“continuation”吗?我看到很多好的例子,尤其是来自这个人。有什么替代方案吗?
一个调用栈。
->
实现了你想要的东西...但是是使用宏来实现的。->
能真正捕捉到OP想要的东西。最好的情况下,->
类似于Identity Monad。现在,如果你可以改变->
来使用任何任意的Monad,那么我会同意你的看法,认为->
足以表达任何使用Continuations的计算(你只需使用Continuation Monad即可)。但是,在Clojure中实现的->
没有提供挂起和恢复计算的方法。First-class Continuations使您完全控制计算的哪些部分运行以及何时运行。这在->
中完全缺失。 - Nathan Davis