2010-10-26 15 views
17

Wie verwenden Menschen Fortsetzungen in einem größeren und kleineren Maßstab in Scala?Verwendet für Scala Fortsetzungen

Sind Teile der Scala-Standardbibliothek in CPS geschrieben?

Gibt es irgendwelche größeren Leistungseinbußen bei der Verwendung von Fortsetzungen?

+5

ein nit: CPS (Fortsetzungsübertragungsstil) etwas ist, das in jeder Sprache möglich ist, das hat oder simulieren Funktionen höherer Ordnung. Wenn Sie beispielsweise ein Callback-Objekt an eine Methode in Java übergeben, ist dies ein Beispiel für CPS. Scalas * delimited continuations * plugin bietet eine Möglichkeit, Kontrollstrukturen zu schreiben, die syntaktisch wie "direkter Stil" aussehen, aber hinter den Kulissen in CPS transformiert werden. –

Antwort

14

ich dies mit asynchronen Funktionen der Form drehen def func(...)(followup: Result => Unit): Unit so dass anstelle des Schreibens

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

Sie können

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

oder

car(bar(foo(args))) 

(Anmerkung schreiben: die Funktionen sind nicht auf ein Argument oder nur die Verwendung vorheriger Ergebnisse als Argumente beschränkt)

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

+0

Dies ist ein ziemlich gutes Beispiel, es hätte wahrscheinlich mehr didaktischen Wert, wenn die Verschachtelung tiefer wäre :) –

7

Scala-ARM (Automatic-Ressource-Management) verwendet begrenzte Fortsetzungen

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

Entschuldigung, aber was sind die Vorteile, wenn man es so schreibt?

Also ist die Fortsetzung 'k', die eine println gefolgt von einer Flush-Anweisung darstellt? Ich sehe nicht die Vorteile der Verwendung von CPS in diesem Fall. –