Ответ: всегда .
escaper
не является частью Схемы. Он определяется этой книгой, Схема и искусство программирования , таким образом:
"escaper
превращает процедуру аргумента в аналогично определенную процедуру 'escape' ( он же «продолжение»), который, когда вызывается, его результат становится результатом всего вычисления. Все, что ожидает результата [вызова этой escape-процедуры], игнорируется ». (слегка отредактировано)
Результат (continuation body)
в версии "escaper
-ed" (lambda (c..n) (c..n body))
будет возвращено непосредственно на верхний уровень, за исключением того, что continuation
не не возвращает . Он переходит в его целевой контекст (1)
, то есть , то , который ожидает результата вызова (call/cc r)
, потому что this 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)
на continuation--1
; и если body
вызывает continuation
со значением, это значение передается в (1)
с помощью continuation--1
. Ничего не возвращается к continuation--0
, поэтому его скачок никогда не срабатывает.
И в
;; (0)
(...
;; (1)
(call/cc (lambda (continuation) body))
...)
===
;; (0)
(...
;; (1)
(let ((continuation continuation--1))
body)
...)
происходит точно то же самое: если body
возвращает , этот результат просто возвращается в (1)
; и если body
вызывает continuation
со значением, это значение передается в (1)
с помощью continuation--1
.