Scala Continuations的用途

17

人们在Scala中如何在较大和较小的规模上使用continuations?

Scala标准库中是否有任何部分是用CPS编写的?

在使用continuations时是否存在任何主要性能惩罚?


5
一个细节:CPS(Continuation-Passing Style)是任何具有高阶函数或可以模拟高阶函数的语言中都可能存在的内容。例如,当您将回调对象传递给Java中的方法时,那实际上就是CPS的一个例子。Scala的“delimited continuations”插件提供了一种编写控制结构的方式,它们在语法上看起来像是“直接样式”,但在后台被转换为CPS。 - Tom Crockett
2个回答

14

我将使用以下内容来转换形如 def func(...)(followup: Result => Unit): Unit 的异步函数,以便不必编写:

foo(args){result1 => 
  bar(result1){result2 => 
     car(result2) {result3 =>
       //etc.
     }
  }
}

你可以编写

val result1 = foo(args)
val result2 = bar(result1)
val result3 = car(result2)
或者
car(bar(foo(args)))

(注意:这些函数不仅限于一个参数,也不仅限于将先前的结果用作参数)

参见http://www.tikalk.com/java/blog/asynchronous-functions-actors-and-cps


这是一个相当不错的例子,如果嵌套更深的话,它可能会有更多的教学价值 :) - Alex Cruise

7

Scala-ARM(自动资源管理)使用了分界限制续体技术。

import java.io._
import util.continuations._
import resource._
def each_line_from(r : BufferedReader) : String @suspendable =
  shift { k =>
    var line = r.readLine
    while(line != null) {
      k(line)
      line = r.readLine
    }
  }
reset {
  val server = managed(new ServerSocket(8007)) !
  while(true) {
    // This reset is not needed, however the  below denotes a "flow" of execution that can be deferred.
    // One can envision an asynchronous execuction model that would support the exact same semantics as below.
    reset {
      val connection = managed(server.accept) !
      val output = managed(connection.getOutputStream) !
      val input = managed(connection.getInputStream) !
      val writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(output)))
      val reader = new BufferedReader(new InputStreamReader(input))
      writer.println(each_line_from(reader))
      writer.flush()
    }
  }
}

1
请问,这样写有什么好处吗?<br/><br/>所以续传是 k,它代表了一个 println 后跟着一个 flush 语句?我没有看到在这种情况下使用 CPS 的好处。 - Mohamed Bana

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接