2013-08-29 9 views
5

La continuazione descrive cosa succede dopo con un certo valore, giusto? Non è solo una funzione che prende un valore e fa un calcolo?Cosa distingue una continuazione da una funzione?

(+ (* 2 3) 5) 

la continuazione di (* 2 3) è (+ _ 5)

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

Qual è il punto di utilizzare call/cc qui dentro e non si utilizza la funzione k?

+0

Non si utilizza 'call/cc' il cui argomento * è * prendendo la continuazione corrente (come funzione). Modifica la tua domanda per usare 'call/cc'! Leggi wikipage su [continuation] (http://en.wikipedia.org/wiki/Continuation) –

+0

Non sto usando call/cc, sto usando una funzione equivalente che rappresenta la continuazione? – ayhid

+0

Continuazione è sintatticamente una funzione ma rappresenta un trasferimento di controllo. Il suo protocollo di chiamata è diverso da quello di una funzione: si suppone che non debba mai tornare. –

risposta

6

Vero. Tutti i programmi hanno continuazioni fino a quando non si ferma. Una continuazione è solitamente un passo nel calcolo eseguito dall'implementazione sottostante.

Il vostro esempio:

(+ (* 2 3) 5) 

La combinazione + dipende dalla combinazione di * per arrivare primi. Pertanto, (+ result 5) rappresenta effettivamente la continuazione di (* 2 3). Non è una procedura in questo contesto però. L'utilità di call/cc è quando si ha una continuazione che si dispiace e si vuole fare qualcos'altro, o si desidera tornare a questo in un secondo momento. Consente di fare il primo:

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

Chiaramente, v'è una divisione che è la continuazione quando il risultato del caso è fatto, ma dal momento che exit è gestito il tutto viene in corto circuito per tornare + Inf.0.

Come lo faresti con una procedura senza ottenere la divisione in seguito? In questo stile, non puoi.

Non è davvero magico poiché Schema converte il tuo codice in Continuation Passing Style(=CPS) e in CPS call/cc non è speciale. Non è un codice di scrittura banale in CPS.

Ecco la definizione di CPS call/cc

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

Congratulazioni! Hai appena inventato lo stile di passaggio continuo! L'unica differenza tra ciò che hai fatto e call/cc è che call/cc lo fa automaticamente e non ti richiede di ristrutturare il tuo codice.

2

Una "continuazione" è l'intero futuro di un calcolo. Ogni punto in un calcolo ha una continuazione che, in termini ingenui, puoi considerare come il contatore di programma corrente e lo stack corrente. La funzione Schema call/cc acquisisce facilmente la configurazione corrente e la impacchetta in una funzione. Quando invochi quella funzione ritorni a quel punto nel calcolo. Quindi, una continuazione è molto diversa da una funzione (ma la funzione di continuazione è, beh, una funzione).

Ci sono due casi più comuni in cui si vedono tipicamente call/cc applicate:

  1. uscita non locale. Stabilisci una continuazione, fai qualche calcolo, per terminare bruscamente il calcolo che invochi la continuazione.

  2. riavviare/reinserire un calcolo. In questo caso si salva la continuazione e quindi si chiama di nuovo come ti pare.

Ecco un esempio per il caso # 1:

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

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

E qui è un esempio per il caso # 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 

Per questo caso # 2 Vale la pena notare che la continuazione riporta al ciclo di lettura-eval-print di livello superiore, che ti dà la possibilità di ri-invocare la continuazione in questo esempio!

Problemi correlati