首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >两种方案“无限回路的制造者”的区别?

两种方案“无限回路的制造者”的区别?
EN

Stack Overflow用户
提问于 2020-11-13 12:45:03
回答 1查看 31关注 0票数 0

在本教程中

Darrell弗格森和Dwight Deugo,2001年9月

使用call/cc“突破一个潜在的无限循环”的模式用下面的Scheme代码来说明(稍作修改,以便在repl.it中运行,并在下面进行注释):

第1部分():“无穷化器”在(尾递归)循环中无限地运行“动作函数”。

代码语言:javascript
运行
复制
(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,该函数一旦到达停止判据,就会调用接收到的延续,从而突破无限循环:

代码语言:javascript
运行
复制
(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

例如:

代码语言:javascript
运行
复制
   (loop-until 4)
The count is: 0
The count is: 1
The count is: 2
The count is: 3
=> 4

备用第1部分():看起来(这里是这么命名的infinitizer,原名为infinite-loop)函数太复杂了。以下几点似乎也有效:

代码语言:javascript
运行
复制
(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))))

我不知道这两个不定式有什么区别吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-13 16:41:26

第一个版本的infinitizer更健壮。如果在运行过程中重新定义了infinitizer,它仍将继续运行。第二种方法在尝试恢复时调用新的定义。

尝试使用以下两种定义来查看两者之间的区别:

代码语言:javascript
运行
复制
(define (action . args)
  (display "In action")
  (newline)
  (set! infinitizer action))

(infinitizer action)

不过,除了像这样的病理病例外,它们应该是同等的。

顺便说一句,重写第一个版本来使用命名的let是更干净的:

代码语言:javascript
运行
复制
(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)))
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64821138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档