Wikipedia 关于Continuation的文章说:
“在任何支持闭包的语言中,都可以以连续传递风格编写程序并手动实现 call/cc。”
要么是真的,我需要知道如何去做,要么是不正确的,需要纠正这种说法。
如果这是真的,请告诉我如何在 Lua 中实现 call/cc,因为我看不到如何。如果 Lua 有 coroutine.clone 函数,
我想我可以手动实现 call/cc 。
如果闭包不足以实现 call/cc 那么还需要什么?
下面的文字是可选的阅读。
PS:Lua 的协程表有一次性延续。coroutine.clone 函数将允许我克隆它以多次调用它,从而有效地使 call/cc 成为可能(除非我误解了 call/cc)。然而,该克隆功能在 Lua 中不存在。Lua IRC 频道上有人建议我使用 Pluto 库(它实现序列化)来编组一个协程,复制它,然后解组它并再次使用它。虽然这可能可行,但我更感兴趣的是 call/cc 的理论实现,以及找到一种语言为了允许其手动实现而需要具备的实际最小功能集是什么。
编辑1:好的,大家帮帮我,这花了我很长时间,因为我不知道任何Scheme,但我想出了一些可以帮助我们的东西。请看下面的代码。第一个是 Scheme 中的程序,第二个是同一个程序,但在 Lua 中。
希望这会帮助我们。我相信我们非常接近。
PS:这些例子取自维基百科关于 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
路亚版
-- 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...
我正在使用适用于 Windows 的 DrScheme 和 Lua - 对于任何想要帮助解决这些问题的人来说,这两个工具易于下载和安装,并且可以正常工作。