2013-08-29 5 views
5

続きは、次に何が起こるかについて説明しています。 これは単なる値をとり、計算を行う関数ではありませんか?継続と機能の区別は何ですか?

(+ (* 2 3) 5) 

(* 2 3)の継続が(+ _ 5)

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

ある機能kを使用してここにいないでcall/ccを使用してのポイントは何ですか?

+0

引数*が現在の継続を(関数として)取っている 'call/cc'は使用しません。あなたの質問を編集して 'call/cc'を使ってください! [continuation]のwikipageを読む(http://en.wikipedia.org/wiki/Continuation) –

+0

私はcall/ccを使用していない、私は同等の関数を使用して継続を表していますか? – ayhid

+0

継続は構文的には機能ですが、制御転送を表します。その呼び出しプロトコルは、関数のものとは異なります。返されることは決してありません。 –

答えて

6

真。すべてのプログラムは停止するまで続きます。 1つの継続は、通常、基礎となる実装によって行われる計算の1ステップです。

あなたの例:

(+ (* 2 3) 5) 

組み合わせ+最初に終了する*組み合わせに依存しています。したがって、(+ result 5)は、実際には(* 2 3)の続きです。しかし、この文脈では手続きではありません。 call/ccの有用性は、あなたが後悔し続けていて、代わりに何か他のことをやりたい、または後でこれに戻ってほしいときです。最初に行うことができます:

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

は明らかに、継続である部門がある場合の結果で行われますが、exitので、短い+ Inf.0を返すように短絡されます全体のことを実行している場合。

手順を実行しても、後でその部門をやらないとどうしますか?このスタイルでは、あなたはできません。

SchemeはあなたのコードをContinuation Passing Style(=CPS)に変換し、CPS call/ccは特別なものではないので、それは本当に魔法ではありません。 CPSのコードを書くのは簡単ではありません。ここで

call/cc

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

おめでとうのCPSの定義です!あなたはちょうど継続継承スタイルを発明しました!あなたが行ったこととcall/ccの唯一の違いは、自動的にcall/ccが実行され、コードを再構成する必要がないことです。

2

「継続」は、計算の将来のすべてです。計算の各ポイントには、単純な意味で、現在のプログラムカウンタと現在のスタックと考えることができる継続があります。 Scheme call/cc機能は、現在の設定を便利にキャプチャし、それを機能にパッケージ化します。その関数を呼び出すと、計算のその時点に戻ります。したがって、継続は関数とは非常に異なります(ただし、継続関数は関数です)。

  1. 非ローカルの出口:

    適用1は、一般的にcall/ccを見ている2つの一般的な例があります。継続を確立し、計算を実行して、継続を呼び出す計算を突然終了させます。

  2. 再計算/再計算。この場合、継続を保存してから、もう一度お電話ください。ここで

は、ケース#1の例である:

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

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

そしてここケース#2の例である。この場合、#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 

それは価値があることを指摘されましたこの続きは、最上位のread-eval-printループに戻ります。この例では、継続を再呼び出しする機会があります!

関連する問題