2012-10-03 24 views
1

在表達式(call/cc (lambda (k) (k 12))),有三個延續:(k 12)(lambda (k) (k 12)),和(call/cc (lambda (k) (k 12)))。哪一個是「當前延續」?下列表達式的當前延續是什麼?

而且在一些書的延續被視爲其正在等待值的過程,當它應用到值,它將立即返回。是對的嗎?

任何人都可以解釋什麼目前的延續是詳細的?

回答

2

之類的東西(k 12)不延續。在更大的程序中,每個子表達式都有一個延續。例如,(* 3 (+ x 42))中的x的延續是(lambda (_) (* 3 (+ _ 42)))

在您的例子中,(call/cc (lambda (k) (k 12)))「當前延續」將是無論是周圍的表達。如果您只是將它輸入到方案提示中,則沒有任何方法提示,因此「當前延續」僅爲(lambda (_) _)。如果您鍵入的內容類似(* 3 (+ (call/cc (lambda (k) (k 12))) 42)),則繼續爲(lambda (_) (* 3 (+ _ 42)))

請注意,用於表示「當前延續」的lambda表達式與call/cc傳入的不同(在您的示例中,名稱爲k)。 k在評估當前延續後具有中止計算的其餘部分的特殊控制效果。

1

在這種情況下,延續是接收call/cc調用的返回值的「東西」。因此:

(display (call/cc (lambda (k) (k 12))) 

具有相同的結果

(display 12) 

延續方案「外觀和感覺」之類的程序,但它們實際上並不表現得像程序。有一件事可以幫助你更好地理解延續是CPS轉型。


在CPS轉換中,不是返回值的函數,而是接受一個繼續參數,並用結果調用延續。所以,一個CPS轉換的函數將被(sqrt 64 k)調用,而不是返回8,它只調用尾部位置的(k 8)

由於延續(在CPS變換函數)是尾部調用,該函數不擔心繼續回來,事實上,在大多數情況下,他們預計不會返回。

考慮到這一點,這裏有一個功能的一個簡單的例子:

(define (hypot x y) 
    (sqrt (+ (* x x) (* y y)))) 

和CPS-轉換後的版本:

(define (hypot x y k) 
    (* x x (lambda (x2) 
      (* y y (lambda (y2) 
        (+ x2 y2 (lambda (sum) 
           (sqrt sum k)))))))) 

(假設*+,並且sqrt已全部CPS也轉化爲接受延續論證)。


所以現在,有趣的部分:一個CPS轉化call/cc具有以下定義:

(define (call/cc fn k) 
    (fn k k)) 

隨着CPS轉換,call/cc是容易理解和容易實現。沒有CPS轉換,call/cc可能需要高度神奇的實現(例如,通過堆棧複製等)。

相關問題