如何解釋 Lisp 中 call cc 的概念?

時間 2021-05-31 06:38:39

1樓:

簡單點的理解就是在(call/cc .......)出現的地方搞出乙個蟲洞的出口,

而蟲洞的入口是(call/cc (lambda (k中出現的 k ,通過 (k ...)的形式將...的求值結果傳送到蟲洞出口的位置, k這個蟲洞入口還可以賦值給別的變數.

其它的就交給別的答主了》.<

2樓:勃珍妮

補充一下 @紅日照小池 池哥的回答,因為看不大懂...

定義函式f

(define (f

return)(

return2)

3)文中說(display (call-with-current-continuation f))

返回值是2

但沒給出call-with-current-continuation函式的具體實現

所以自己實現了一下

(define (call-with-current-continuation f)

(call/cc(lambda(x)(f x)))

這時候我們可以知道

(display (call-with-current-continuation f))

等價於(display (call/cc (lambda(f)(f 2)(3))))

那麼call/cc捕獲的continuation應該是display

即display作為實參傳入lambda裡面,替換掉f

而call/cc在呼叫到形參f的時候,會立即跳出

所以(f display)返回了2和3

而變成call/cc之後只返回了2....

(盡可能詳細了,有點囉嗦

3樓:someone

其實想要解釋callCC, 用haskell非常簡單callCC f=cont $ \h->runCont (f (\a->cont $ \_->h a)) h

關鍵是\_這個地方, 明白了這個,就明白了一切。

\_可以概括為, 呼叫f的瞬間, 就忽略了接下來的continuation, 把a直接傳給了h。參考

4樓:StoneBricks

lisp裡提供操控continuation的operator有許多,好像沒有call/cc

scheme選了call/cc,是因為這幫人對語言追求精緻,所以找了乙個威力最大的

其實call/cc的syntax挺醜陋的,他們自己也承認的

5樓:

Springer&Friedman的Scheme and the art of programming-chapter16 中有對call/cc的詳細解釋,可以參考。

那裡引入了context(上下文)和escaper(逃逸子)兩個過程,有助於理解。

首先, context是乙個單參過程,比如(+ 2 (* 3 4))中3的context就是:

(lambda

(hole)(

+ 2(*

hole

4)))

其次, escaper就是將乙個過程逃逸地呼叫,比如(+

12(*

3((escaper

sin)

4)))

;;=>

(sin 4)

也就是說無論escaper外面的環境怎樣,表示式只計算被escaper包含的過程所要計算的部分,也就是逃逸了. 但須注意,如果escaper沒有被呼叫, 那麼自然就沒有逃逸了, 比如

(+ 1 2 (* 3 ((if (> 1 0cosescaper sin));;不會呼叫escaper, 故不逃逸4)))

;;=>

(+ 1 2 (* 3 (cos 4)))

現在可以解釋call/cc的含義了. 乙個含有call/cc的過程是把 (call/cc receiver)所在的上下文(是乙個過程)做成逃逸形式, 並且被另乙個過程receiver呼叫:

(body1

(call/cc

receiver

)body2

);;=>

(body1

(receiver

(escaper

(context

)))body2

);;其中context就是(call/cc receiver)的上下文,即

(lambda

(hole)(

body1

hole

body2

));;continuation 就是逃逸的上下文: (escaper (context))

6樓:

這是一種特定用途的逃逸結構.

如果不從理論來講,直接看r5rs規範中的例子,可以先有個直觀的理解:

(call-with-current-continuation

(lambda

(exit)(

for-each

(lambda (x

)(if (

negative? x)

(exitx)

`()))`(

54037-3

24519

));;在-3處結束

#t))=-3

;;如果把-3改為3

(call-with-current-continuation

(lambda

(exit)(

for-each

(lambda (x

)(if (

negative? x)

(exitx)

`()))`(

540373

24519

));;-3->3,由於沒有直接滿足的,所以結束時是exit的值

#t))=#t

也就是類似break的效果.

由於沒有break,scheme想要實現跳轉的方式,當for-each中的條件滿足時,也就是被求值時,過程就結束了.

呼叫call/cc時,產生乙個等待引數的過程,在引數(這裡的exit)之後的程式稱為current-continuation.

Racket文件中的詳細定義是這樣的:

10.4 Continuations

(call-with-current-continuation proc

prompt-tag]) → any

proc : (continuation? . -> . any)

prompt-tag : continuation-prompt-tag?

default-continuation-prompt-tag)

Captures the current continuation up to the nearest prompt tagged by prompt-tag; if no such prompt exists, the exn:fail:contract:

continuation exception is raised. The truncated continuation includes only continuation marks and dynamic-wind frames installed since the prompt.

The capture continuation is delivered to proc, which is called in tail position with respect to the call-with-current-continuation call.

A continuation can be invoked from the thread (see Threads) other than the one where it was captured.

7樓:

(call/cc (lambda (k) BODY))或者少點括號用這個

(let/cc k BODY)

continuation是「然後要做的事情」,「要做的事情」我們用什麼表示?當然是函式,所以說k是個函式。

如果我們在BODY裡呼叫了(k ...),那麼會立即跳出(let/cc k BODY),去做下乙個括號/外層括號的事。

那麼剛才(let/cc k BODY)沒執行完,它的返回值是什麼呢?就是你傳給k的引數。

8樓:Irons Du

本來應該執行A,但call/cc(流程)跳轉執行到另外乙個地方,且把A傳遞過去,以後再通過呼叫A返回到原來A的執行流程。

整個執行流程是以樹的形式表達,而不是傳統C/C++堆幀的形式。

如何解釋material design中,關於卡片的三層投影?

UTL1138 三層陰影為關鍵光投射的本影和半影以及環境光投射的環境陰影。從官方規範中可知三層陰影中的兩層就是原來Key Shadow 關鍵光 進行了細分。所以此前的兩層陰影並不是本影和半影,而只是關鍵光和環境光投射的兩種陰影。Shadows Resources Material Design 天 ...

如何解釋 Haskell 中的單子(Monad)?

陳斌 自函子的Monoidal範疇上的乙個么半群.么半群是指.大概意思.原群 這班裡全是小學生,希望揍他們任意有限次後還是小學生.這在拓撲概念裡可能要求更過分,揍任意無數次必須還是小學生.半群 在原群基礎上,小學生排好隊了之後,我希望先揍任意相鄰兩個,結果都一樣.么半群 在半群基礎上,希望這群小學生...

如何解釋哲學中自然傾向(metaphysica naturalis)一詞?

清雲 康德說的 形上學的自然傾向 的意思,應該是指人的理性傾向,也就是說人的理性具有超出經驗範圍的有條件者,去尋求無條件者的傾向。具體而言,理性會把乙個判斷推到極端,得出理念。這些無條件者 理性的理念 包括靈魂 上帝 世界 自由等理念。比如靈魂作為無條件者,就是乙個不再作為賓詞的主詞,上帝作為無條件...