`values` 在 Scheme 中是如何工作的?
How does `values` work in Scheme?
来自R5RS标准:
Values might be defined as follows:
(define (values . things)
(call-with-current-continuation
(lambda (cont) (apply cont things))))
我对此的第一个解释是像 (+ (values 1 2))
这样的表达式等同于 (apply + '(1 2))
并且会产生结果 3
。但是,根据我的测试,这种解释是不正确的。以下是我对上面代码的解释:values
是一个函数,可以接受任意数量的参数,捆绑到一个名为 things
的列表中。然后,使用列表 things
"unbundled".
调用当前延续(使用 values
的地方)
我错过了什么?上面的示例 (+ (values 1 2))
根据我使用的解释器给出错误或 1。
看,当你输入时
(+ (values 1 2))
对 values
的调用的延续实际上是 对 +
的单个 参数。因此,它要么被视为 1(列表的第一个元素,过程产生的第一个值),要么被视为错误。 R5RS对此表示:
Except for continuations created by the call-with-values procedure, all continuations take exactly one value. The effect of passing no value or more than one value to continuations that were not created by call-with-values is unspecified.
另一方面,call-with-values
会正确地将列表的元素绑定到它的 consumer
参数的正式参数:
Calls its producer argument with no values and a continuation that, when passed some values, calls the consumer procedure with those values as arguments.
为了理解 values
的这个定义的含义,您还需要理解 call-with-current-continuation
的定义,它是根据它定义的。 values
的文档提到了 call-with-values
,作为如何使用 values
.
结果的示例很有帮助
因此,您可以在以下上下文中使用 (values 1 2)
:
(call-with-values (lambda () (values 1 2))
(lambda (x y) (+ x y)))
来自R5RS标准:
Values might be defined as follows:
(define (values . things)
(call-with-current-continuation
(lambda (cont) (apply cont things))))
我对此的第一个解释是像 (+ (values 1 2))
这样的表达式等同于 (apply + '(1 2))
并且会产生结果 3
。但是,根据我的测试,这种解释是不正确的。以下是我对上面代码的解释:values
是一个函数,可以接受任意数量的参数,捆绑到一个名为 things
的列表中。然后,使用列表 things
"unbundled".
values
的地方)
我错过了什么?上面的示例 (+ (values 1 2))
根据我使用的解释器给出错误或 1。
看,当你输入时
(+ (values 1 2))
对 values
的调用的延续实际上是 对 +
的单个 参数。因此,它要么被视为 1(列表的第一个元素,过程产生的第一个值),要么被视为错误。 R5RS对此表示:
Except for continuations created by the call-with-values procedure, all continuations take exactly one value. The effect of passing no value or more than one value to continuations that were not created by call-with-values is unspecified.
另一方面,call-with-values
会正确地将列表的元素绑定到它的 consumer
参数的正式参数:
Calls its producer argument with no values and a continuation that, when passed some values, calls the consumer procedure with those values as arguments.
为了理解 values
的这个定义的含义,您还需要理解 call-with-current-continuation
的定义,它是根据它定义的。 values
的文档提到了 call-with-values
,作为如何使用 values
.
因此,您可以在以下上下文中使用 (values 1 2)
:
(call-with-values (lambda () (values 1 2))
(lambda (x y) (+ x y)))