【问题标题】:how to analyze the equivalent receiver in call/cc?如何分析呼叫/抄送中的等效接收者?
【发布时间】:2020-08-10 20:40:53
【问题描述】:

我正在阅读Scheme and the Art of Programming这本书,但想不出以下问题的答案:

如果 r

(escaper (lambda (continuation) (continuation body))

(... (call/cc r) ...)中,r什么时候可以改写为

(lambda (continuation) body)

【问题讨论】:

  • escaper 不是 Scheme 的一部分。它是由那本书Scheme and the Art of Programming定义的,因此提及它很重要。 " escaper 将其参数过程转换为类似定义的“转义”过程(又名“延续”),当被调用时,它的结果将成为整个计算的结果。任何等待结果的任何[该转义过程的调用] 被忽略。”(略作复制编辑)
  • (call/cc r) 可以出现在该表达式的任何位置。这就是... ... 的含义。
  • 如果r(escaper (lambda (continuation) (continuation body)))(r continuation) 的结果仍然是(continuation body),因为continuation 也是一个转义过程并且首先被调用。 r 是(escaper (lambda (continuation) (continuation body)))(lambda (continuation) (continuation body)) 没有区别。 (对不起我的英语不好)
  • 你重复我回答的结论。 :) 我在到达它时更加小心。我提供翻译并仔细研究。但是,如果它对你来说那么清楚,你为什么要问? :) 但你问得很好,它给了我一个完成这个练习的机会。 :) 干杯!
  • 很高兴能提供帮助。 :) (注意使用let 重写。当我进行此类重写时,它通常可以帮助我理解代码,例如with y-combinator

标签: scheme racket continuations callcc


【解决方案1】:

答案是:总是

escaper 不是方案的一部分。它是由那本书Scheme and the Art of Programming定义的,因此:

" escaper 将其参数过程转换为类似定义的“转义”过程(又名“延续”),当调用该过程时,其结果将成为整个计算的结果。任何等待结果的 [那个逃逸过程的调用]被忽略。” (略有复制)

(continuation body)的结果(lambda (c..n) (c..n body))的“escaper-ed”版本中会直接返回顶级,除了continuation返回。它跳转它的目标上下文(1),即等待(call/cc r)调用结果的那个,因为这个 continuation 是通过调用 call/cc 设置的:

           ;; (0)   -- top level
             (... 
                  ;; (1)  <-----------------------------------\
                    (call/cc r)  ;; r = (escaper (lambda (continuation)
                                 ;;                 (continuation body)))
                         ...)
===
           ;; (0)   -- top level
             (... 
                  ;; (1)  
                    (continuation--0                       ;; set up by `escaper`
                      ((lambda (continuation)
                            (continuation body))
                        continuation--1))                   ;; set up by call/cc
                         ...)
===
           ;; (0)   -- top level
             (... 
                  ;; (1)  
                    (continuation--0
                       (let ((continuation continuation--1))   ;; by application of `lambda`
                         (continuation body)))
                         ...)

因此,如果body 返回,则该结果由continuation--1 传递给(1);如果body 调用 continuation 带有一个值,则该值将由continuation--1 传递给(1)continuation--0 没有返回任何内容,因此它的跳转永远不会被触发。

           ;; (0)
             (... 
                  ;; (1)
                    (call/cc (lambda (continuation) body))
                         ...)
===
           ;; (0)
             (... 
                  ;; (1)
                    (let ((continuation continuation--1)) 
                       body)
                         ...)

完全相同的事情发生:如果body 返回,则该结果将简单地返回到(1);如果body 调用 continuation 带有一个值,则该值将由continuation--1 传递给(1)

【讨论】:

    猜你喜欢
    • 2012-02-21
    • 2015-04-23
    • 2016-06-07
    • 1970-01-01
    • 2011-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多