[英]What does a continuation return in Scheme?
I came across something that I can not understand. 我遇到了一些我无法理解的东西。
#lang scheme
(define cc #f)
(define (val!)
(call/cc
(lambda (k)
(set! cc k)
0)))
(* 10 (val!))
(cc 100)
So far so good; 到现在为止还挺好; the continuation of
(* 10 [])
is stored in cc
and if we call (cc 100)
we see 1000
in the REPL as expected. (* 10 [])
的延续存储在cc
,如果我们调用(cc 100)
我们会按预期在REPL中看到1000
。
But the next thing I tried was to define a variable to be the result of running the continuation: 但我接下来尝试的是将变量定义为运行延续的结果:
(define x (cc 20))
I see 200
as a result in the REPL, but x
does not get defined. 我在REPL中看到
200
是结果,但x
没有定义。
Does the continuation stored in cc
include its returning so that the call to define
never returns and instead the evaluation is the result of (* 10 val)
? 存储在
cc
的continuation是否包含它的返回值,以便define
的调用永远不会返回,而评估是(* 10 val)
? What is going on? 到底是怎么回事?
There are two types of continuations. 有两种类型的延续。
A continuation produced by call/cc
never returns a value to its caller. call/cc
产生的延续从不向其调用者返回值。 See Will Ness's answer for more on that. 请参阅Will Ness的答案 。
But the continuations produced by call-with-composable-continuation
are composable continuations, which do return values. 但是,通过
call-with-composable-continuation
continuation产生call-with-composable-continuation
是可组合的延续,它确实返回值。
If you want a continuation to return a value to its caller, you should use a composable continuation, by setting up a prompt and using call-with-composable-continuation
. 如果要继续向其调用者返回值,则应使用可组合的延续,通过设置提示并使用
call-with-composable-continuation
。
You can define a kind of prompt: 您可以定义一种提示:
(define my-prompt
(make-continuation-prompt-tag 'my-prompt))
And use the prompt in call-with-composable-continuation
to specify that you only want to capture the continuation starting from the prompt. 并使用
call-with-composable-continuation
的提示指定您只想从提示符开始捕获延续。
(define cc #f)
(define (val!)
(call-with-composable-continuation
(lambda (k)
(set! cc k)
0)
my-prompt))
Then you just have to put the prompt wherever you want the continuation to start before you call val!
然后你只需要在你打电话给
val!
之前把提示放在你希望继续的地方val!
to save it. 保存它。
;; the prompt specifies that it's `(* 10 [])`, and not something larger
(call-with-continuation-prompt
(λ () (* 10 (val!)))
my-prompt)
Then, since this continuation has a clear "end" defined by the prompt, it can return a value when it reaches that end. 然后,由于此延续具有由提示定义的明确“结束”,因此它可以在到达该结束时返回值。
(define x (cc 20))
; defines x as 200
See also: What exactly is a "continuation prompt?" 另请参阅: “持续提示”究竟是什么?
It returns nothing, because it does not return. 它什么都不返回,因为它没有返回。
(cc 20)
, just as (cc 100)
, does not return a value to its caller. (cc 20)
正如(cc 100)
不将值返回给调用者。 cc
is not a function, it is a continuation - it remembers where to return / "feed" its value, by itself. cc
不是一个函数,它是一个延续 - 它记住它自己返回/ “提供”其值的位置。
(define x (cc 20))
means, approximately, in pseudocode, 大概是指伪代码,
(let ([val (cc 20)])
(primitive-define-top-level-var! "x" val))
but (cc 20)
bypasses the setting of val
and using it to define x
, and returns directly to the top level, as was done by the original captured continuation. 但是
(cc 20)
绕过val
的设置并使用它来定义x
,并直接返回到顶层,就像原始捕获的延续一样。
Does the continuation stored in
cc
include its returning [ "destination" -- wn] so that the call todefine
never returns and instead the evaluation is the result of(* 10 val)
?存储在
cc
的continuation是否包含其返回的[ “destination” - wn],以便define
的调用永远不会返回,而评估是(* 10 val)
?
Yes. 是。
What is going on?
到底是怎么回事?
Exactly that. 确切地说。
edit: 编辑:
Loading the following in DrRacket, 在DrRacket中加载以下内容,
#lang scheme
(define cc #f)
(define (val!)
(call/cc
(lambda (k)
(set! cc k)
0)))
(* 10 (val!))
(cc 100)
(display "Good!\n")
(define x (cc 20))
(display "Shucks!\n")
I even get an error message explaining what is going on: 我甚至收到一条错误消息,解释发生了什么:
Language: scheme, with debugging;
语言:方案,调试; memory limit: 128 MB.
内存限制:128 MB。
00
10001000
Good!好!
200200
define-values: skipped variable definition;define-values:跳过的变量定义;
cannot continue without defining variable没有定义变量就无法继续
variable: x变量:x
in module: 'anonymous-module在模块中:'匿名模块
>>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.