“值”如何在Scheme中起作用?

时间:2018-04-03 23:06:03

标签: scheme lisp apply r5rs callcc

来自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的列表中。然后,使用列表values“unbundled”调用当前继续(使用things的位置)。

我错过了什么?上面的示例(+ (values 1 2))给出错误或1,具体取决于我使用的解释器。

2 个答案:

答案 0 :(得分:4)

当您输入

时,请参阅
(+ (values 1 2))

继续调用values实际上是{em> +的单个参数。因此,它被视为1(列表的第一个元素,过程产生的第一个值)或错误。 R5RS在这方面说:

  

除了使用call-with-values过程创建的continuation之外,所有continuation都只接受一个值。未指定值或多个值传递给未通过call-with-values创建的continuation的效果。

另一方面,call-with-values会正确地将列表的元素绑定到其consumer参数的正式参数:

  

调用其生成器参数时没有值和延续,当传递一些值时,会将这些值作为参数调用使用者过程。

答案 1 :(得分:0)

为了理解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)))