首页 > 解决方案 > 如何分析呼叫/抄送中的等效接收者?

问题描述

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

如果r

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

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

(lambda (continuation) body)

标签: schemeracketcontinuationscallcc

解决方案


答案是:总是

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

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

(continuation body) escaper-ed”版本的(lambda (c..n) (c..n body)) 结果直接返回到顶层,但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 返回,则该结果将传递给(1)by continuation--1; 如果使用值body 调用 continuation,则该值将传递给(1)by continuation--1。没有返回任何东西continuation--0,所以它的跳转永远不会被触发。

而在

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

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


推荐阅读