上Continuation維基百科的文章說:
「在支持關閉任何語言,可以寫在延續傳遞風格的程序和手動執行呼叫/立方厘米。」
要麼這是真的,我需要知道如何去做,否則它是不正確的,該聲明需要糾正。
如果這是真的,請告訴我如何在Lua中實現call/cc,因爲我看不到如何。
我想我可以手動實現call/cc,如果Lua具有corruptine.clone函數,如here所解釋的那樣。
如果閉包不足以實現call/cc,那麼還需要什麼?呼叫/ cc在Lua - 可能嗎?
以下文本是可選閱讀。
P.S .: Lua對其協程表進行了一次性延續。一個coroutine.clone函數可以讓我克隆它多次調用它,從而有效地使call/cc成爲可能(除非我誤解了call/cc)。然而,克隆功能在Lua中不存在。 Lua IRC頻道上的某個人建議我使用Pluto庫(它實現序列化)來封送協同程序,複製它,然後解組並再次使用它。雖然這可能會起作用,但我對call/cc的理論實現以及查找語言爲實現其手動實現所需的實際最小特徵集合更感興趣。
編輯1:好的人,幫我在這裏,這花了我很長一段時間,因爲我不知道任何計劃,但我想出了什麼,應該幫助我們。請看下面的代碼。第一個是Scheme中的程序,第二個是Lua中的程序。
希望這會幫助我們。我相信我們非常接近。
P.S .:這些示例取自the Wikipedia article on CallCC上的第一個示例。 方案版本
(define call/cc call-with-current-continuation)
; callcc CPS-transformed (thanks to the people from the #scheme channel at freenode.net)
(define cpscallcc
(lambda (consumer k)
(let ((cc (lambda (result) (k result))))
(consumer cc k))))
; this is the continuation we will use to display the "returned" values
(define main-continuation
(lambda (result)
(display "--> ")
(display result)
(newline)))
; define f function non-CPS
(define (f return)
(return 2)
3)
; these are my past attempts at defining a CPS f function
;(define (cps-f return k)
; (k (return 2)) 3)
;(define (cps-f return k)
; (k (lambda()
; (return 2)
; 3)))
; this is what I came up with - I'm not sure if this is correctly CPS-transformed but I believe so
(define (cps-f return k)
(return 2)
(k 3))
; call the non-CPS f function
(display (f (lambda (x) x))) ; displays 3
(newline)
; call the non-CPS f function with call/cc (I don't understand what this does)
(display (call/cc f)) ; displays 2
(newline)
; now call the CPS version of the f function
(cps-f (lambda (x) x) main-continuation) ; displays --> 3
; now call the CPS version of the f function with the CPS version of call/cc
(cpscallcc cps-f main-continuation) ; displays --> 2 but then it also displays --> 3 afterwards -> I'm not sure why it displays the 3 afterwards, as it should only display the 2 just like the non-CPS versions above
Lua版本
-- callcc CPS-version
cpscallcc = function(consumer, k)
local cc = function(result)
return k(result) -- ?or k(result)
end
return consumer(cc, k) -- ?or return consumer(cc,k)
end
-- define f function non-CPS
f = function(ret)
ret(2)
return 3
end
-- define f function CPS-version (again, not sure this is correct)
cps_f = function(ret, k)
ret(2)
k(3)
end
-- call the non-CPS f function
print(f(function(x) return x end))
-- we cant call the non-CPS f function with callcc because
-- Lua doesnt have callcc, but the line below displays the correct expected output (maybe by accident)
--cpscallcc(f, print)
-- now call the CPS version of the f function
cps_f(function(x) return x end, print) -- displays 3
; now call the CPS version of the f function with the CPS version of call/cc
cpscallcc(cps_f, print) -- displays 2 and then 3 just like the Scheme version!!
-- so apparently the translation from Scheme to Lua is correct...
我使用DrScheme和Lua的Windows - 對於任何人,願意幫助了出這是兩個方便下載和安裝剛剛工作的工具。
哇,你讓我真的接近理解這一點。你可以擴展callcc函數的定義嗎?特別是通過解釋允許它記住保存/記住所有狀態的部分,如Scheme的call/cc所做的。 – PeterM 2010-05-13 16:37:03
我想我會遇到麻煩,如何使用這個callcc函數 - 在Scheme中你必須設置一個呼叫/ cc跳轉到的地方,但是在CPS中你不會......這讓我想起了我。 – PeterM 2010-05-13 16:43:45
因爲k是callcc將返回的閉包,所以將它傳遞給它的參數f完成了call/cc的工作[我剛剛編輯了上面的定義,因爲我忘記了正確地返回]。當程序處於CPS時,這是微不足道的,因爲延續總是可用的;在Scheme中,隱藏的和call/cc的工作比較困難(在語言層面上,編譯器的實現可能很微不足道),因爲它必須「延續」這個延續。 – 2010-05-13 17:25:45