2013-08-29 11 views
5

Fortsetzung beschreibt, was als nächstes mit einem gewissen Wert passiert, oder? Ist das nicht nur eine Funktion, die einen Wert nimmt und etwas berechnet?Was unterscheidet eine Fortsetzung von einer Funktion?

(+ (* 2 3) 5) 

die Fortsetzung der (* 2 3) ist (+ _ 5)

(define k (lambda (v) (+ v 5))) 

Was der Punkt ist call/cc hier verwenden und nicht die Funktion k mit?

+0

Sie verwenden 'call/cc' nicht, dessen Argument * die aktuelle Fortsetzung (als Funktion) ist. Bearbeiten Sie Ihre Frage, um 'call/cc' zu verwenden! Wikipage lesen auf [Fortsetzung] (http://en.wikipedia.org/wiki/Continuation) –

+0

Ich benutze nicht Call/cc, verwende ich eine äquivalente Funktion repräsentiert die Fortsetzung? – ayhid

+0

Die Fortsetzung ist syntaktisch eine Funktion, aber sie stellt eine Steuerungsübertragung dar. Sein Anrufprotokoll ist anders als das einer Funktion - es soll nie zurückkehren. –

Antwort

6

Wahr. Alle Programme haben Fortsetzungen bis zum Stillstand. Eine Fortsetzung ist normalerweise ein Schritt in der Berechnung, die von der zugrunde liegenden Implementierung durchgeführt wird.

Ihr Beispiel:

(+ (* 2 3) 5) 

Die Kombination + ist auf der Kombination abhängig * zuerst zu beenden. Somit ist (+ result 5) in der Tat die Fortsetzung von (* 2 3). Es ist jedoch keine Prozedur in diesem Zusammenhang. Die Nützlichkeit von call/cc ist, wenn Sie eine Fortsetzung haben, die Sie bedauern, und möchten stattdessen etwas anderes tun, oder Sie möchten zu einem späteren Zeitpunkt darauf zurückkommen. Lets tun, um die erste:

(define g 0) 
(call/cc 
    (lambda (exit) 
    (/ 10 (if (= g 0) (exit +Inf.0) g)))) 

Offensichtlich gibt eine Abteilung, die die Fortsetzung ist, wenn das Ergebnis der, wenn gemacht wird, aber da exit wird das Ganze ausgefuehrt wird kurzgeschlossen + Inf.0 zurückzukehren.

Wie würden Sie das mit einer Prozedur machen, ohne dass Sie danach die Division machen? In diesem Stil können Sie nicht.

Es ist nicht wirklich Magie, da Schema Ihren Code in Continuation Passing Style(=CPS) konvertiert und in CPS Call/CC ist keine spezielle. Es ist kein trivialer Code in CPS.

Hier ist die CPS Definition von call/cc

(define (kcall/cc k consumer) 
    (consumer k (lambda (ignore v) (k v)))) 
4

Herzlichen Glückwunsch! Sie haben gerade den Fortsetzungsstil erfunden! Der einzige Unterschied zwischen dem, was Sie getan haben, und call/cc ist, dass call/cc automatisch ausgeführt wird und Sie Ihren Code nicht neu strukturieren müssen.

2

Eine "Fortsetzung" ist die gesamte Zukunft einer Berechnung. Jeder Punkt in einer Berechnung hat eine Fortsetzung, die Sie sich naiv als den aktuellen Programmzähler und den aktuellen Stapel vorstellen können. Die Funktion Scheme call/cc erfasst bequem die aktuelle Konfiguration und packt sie zu einer Funktion zusammen. Wenn Sie diese Funktion aufrufen, kehren Sie zu diesem Punkt in der Berechnung zurück. Somit ist eine Fortsetzung sehr verschieden von einer Funktion (aber die Fortsetzungsfunktion ist, na ja, eine Funktion).

Es gibt zwei Fälle, in denen man typischerweise call/cc angewendet sieht:

  1. nicht lokalen Ausgang. Sie stellen eine Fortsetzung her, machen eine Berechnung, um die Berechnung abrupt zu beenden, rufen Sie die Fortsetzung auf.

  2. neustarten/erneut eine Berechnung eingeben. In diesem Fall speichern Sie die Fortsetzung und rufen sie dann wie gewünscht wieder auf.Hier

ist ein Beispiel für Fall # 1:

(begin 
    ;; do stuff 
    (call/cc (lambda (k) 
       ;; do more 

      ;; oops, must 'abort' 
      (k 'ignore))) 
    ;; continue on 
) 

Und hier ist ein Beispiel für Fall # 2:

> (define C#f) 
> (let ((x 10)) 
    (display (list (+ 1 (call/cc (lambda (k) (set! c k) x))) 111)) 
    (display " more")) 
(11 111) more 
> (c 20) 
(21 111) more 
> (c 90) 
(91 111) more 

Für diesen Fall # 2 ist es erwähnenswert, dass Die Fortsetzung bringt Sie zurück in die Lese-Eval-Print-Schleife auf oberster Ebene - mit der Sie die Fortsetzung in diesem Beispiel erneut aufrufen können!

Verwandte Themen