`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)))