Reputation: 2343
From the R5RS standard:
Values might be defined as follows:
(define (values . things)
(call-with-current-continuation
(lambda (cont) (apply cont things))))
My first interpretation of this was that an expression like (+ (values 1 2))
is equivalent to (apply + '(1 2))
and would yield the result 3
. But, according to my tests, this interpretation is not correct. Here is my interpretation of the code above: values
is a function taking any number of arguments, bundled into a list called things
. Then, the current continuation (the place where values
is used) is called with the list things
"unbundled".
What am I missing? The example above (+ (values 1 2))
gives an error or 1 depending on the interpreter I used.
Upvotes: 4
Views: 2141
Reputation: 92067
In order to understand what this definition of values
means, you need to also understand the definition of call-with-current-continuation
, which it is defined in terms of. And helpfully, the documentation for values
mentions call-with-values
, as an example of how to use the result of values
.
So, you could use (values 1 2)
in a context like:
(call-with-values (lambda () (values 1 2))
(lambda (x y) (+ x y)))
Upvotes: 3
Reputation: 11940
See, when you type
(+ (values 1 2))
the continuation of the call to values
is actually a single argument to +
. So, it is either treated as 1 (the first element to the list, the first value produced by the procedure), or an error. R5RS says in this regard:
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.
On the other hand, call-with-values
would correctly bind your list's elements to its consumer
argument's formal arguments:
Calls its producer argument with no values and a continuation that, when passed some values, calls the consumer procedure with those values as arguments.
Upvotes: 6