簡體   English   中英

延續與功能的區別是什么?

[英]What distinguishes a continuation from a function?

延續描述接下來會發生什么價值,對吧? 這不僅僅是一個獲取值並進行一些計算的函數嗎?

(+ (* 2 3) 5)

(* 2 3)的延續是(+ _ 5)

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

在這里使用call/cc而不使用函數k什么意義?

真正。 所有程序都有延續,直到它停止。 一個延續通常是底層實現計算的一個步驟。

你的例子:

(+ (* 2 3) 5)

組合+取決於組合*首先完成。 因此(+ result 5)確實是(* 2 3)的延續。 但是,這不是這種情況下的程序。 call/cc的用處是當你有一個遺憾而后悔並且想要做其他事情或者你想在以后再回到這個時候。 讓我們做第一個:

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

顯然,有一個除法是if的結果完成時的延續,但是由於exit運行,整個東西被短路返回+ Inf.0。

你怎么會用一個程序來做到這一點而不讓它在之后進行划分? 在這種風格,你不能。

由於Scheme將您的代碼轉換為Continuation Passing Style(= CPS)並且在CPS call / cc中沒有特殊之處,因此這並不是真正的魔力。 在CPS中編寫代碼並非易事。

這是call/cc的CPS定義

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

恭喜! 你剛剛發明了延續傳遞風格! 你所做的和call/cc之間的唯一區別是call/cc會自動執行,並且不需要你重構你的代碼。

“延續”是計算的整個未來。 計算中的每個點都有一個延續,在幼稚的條件下,你可以將其視為當前的程序計數器和當前堆棧。 Scheme call/cc函數可以方便地捕獲當前配置並將其打包成一個函數。 當您調用該函數時,您將恢復到計算中的那一點。 因此,延續與函數非常不同(但是延續函數是一個函數)。

有兩種常見情況,其中通常會看到應用的call/cc

  1. 非本地出口。 你建立一個延續,做一些計算,突然結束你調用延續的計算。

  2. 重新啟動/重新輸入計算。 在這種情況下,您可以保存延續,然后根據需要再次調用它。

以下是案例#1的示例:

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

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

以下是案例#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

對於這種情況,#2值得注意的是,延續會將您帶回到頂級的read-eval-print循環 - 這使您有機會重新調用此示例中的延續!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM