在本教程中
Darrell弗格森和Dwight Deugo,2001年9月
使用call/cc
“突破一个潜在的无限循环”的模式用下面的Scheme代码来说明(稍作修改,以便在repl.it中运行,并在下面进行注释):
第1部分():“无穷化器”在(尾递归)循环中无限地运行“动作函数”。
(define infinitizer
(lambda (action-function)
; "loop" is a closure taking no parameters which calls
; "action-procedure" and then calls "loop".
; After defining it, just call "loop".
(letrec
((loop
(lambda ()
(begin
; ... code to execute before each action would go here ...
(action-function)
; ... code to execute after each action would go here ...
(loop)))))
(loop))))
Part 2:例如,这是在toplevel作为(loop-until 4)
调用的函数。它使用一个receiver
调用call/cc
,该receiver
调用计数动作函数周围的infinitizer
,该函数一旦到达停止判据,就会调用接收到的延续,从而突破无限循环:
(define loop-until
(lambda (n)
(let
((receiver
(lambda (exit-function) ; exit-function will be the "current continuation" at call
(let ((count 0)) ; count will be mutated using "set!"
(infinitizer
(lambda () ; this is the action-function
(if (= count n) ; breakoff criterium
(exit-function count) ; call received continuation with exit value
(begin
(display "The count is: ")
(display count)
(newline)
; communicate with the next action-function
; instance by POKE-ing count
(set! count (+ count 1)
))))))))) ; end of receiver definition
(call/cc receiver)))) ; call with the above receiver
例如:
(loop-until 4)
The count is: 0
The count is: 1
The count is: 2
The count is: 3
=> 4
备用第1部分():看起来(这里是这么命名的infinitizer
,原名为infinite-loop
)函数太复杂了。以下几点似乎也有效:
(define infinitizer
(lambda (action-function)
(begin
;;; ... code to execute before each action would go here ...
(action-function)
;;; ... code to execute after each action would go here ...
(infinitizer action-function))))
我不知道这两个不定式有什么区别吗?
发布于 2020-11-13 16:41:26
第一个版本的infinitizer
更健壮。如果在运行过程中重新定义了infinitizer
,它仍将继续运行。第二种方法在尝试恢复时调用新的定义。
尝试使用以下两种定义来查看两者之间的区别:
(define (action . args)
(display "In action")
(newline)
(set! infinitizer action))
(infinitizer action)
不过,除了像这样的病理病例外,它们应该是同等的。
顺便说一句,重写第一个版本来使用命名的let是更干净的:
(define (infinitizer action-function)
(let loop ()
;; ... code to execute before each action would go here ...
(action-function)
;; ... code to execute after each action would go here ...
(loop)))
https://stackoverflow.com/questions/64821138
复制相似问题