The multiple-value feature was added in R5RS.
Delivers all of its arguments to its continuation.
Calls its producer argument with no arguments and a continuation that, when passed some values, calls the consumer procedure with those values as arguments.
(call-with-values (lambda () (values 4 5)) (lambda (a b) b)) ⇒ 5 (call-with-values * -) ⇒ -1
Performance note: If either the producer or consumer is a fixed-arity lambda expression, it is inlined.
It is an error if a variable appears more than once in the set of formals.
The expression is evaluated, and the formals
are bound to the return values in the same way that the formals in
lambda expression are matched to the arguments in a procedure call.
(define-values (x y) (integer-sqrt 17)) (list x y) ⇒ (4 1) (let () (define-values (x y) (values 1 2)) (+ x y)) ⇒ 3
Each formals should be a formal arguments list, as for a
The expressions are evaluated in the current environment, the variables of the formals are bound to fresh locations, the return values of the expressions are stored in the variables, the body is evaluated in the extended environment, and the values of the last expression of body are returned. The body is a "tail body", cf section 3.5 of the R5RS.
The matching of each formals to values is as for the matching of
formals to arguments in a
lambda expression, and it is an
error for an expression to return a number of values that does not
match its corresponding formals.
(let-values (((a b . c) (values 1 2 3 4))) (list a b c)) ⇒ (1 2 (3 4)) (let ((a 'a) (b 'b) (x 'x) (y 'y)) (let-values (((a b) (values x y)) ((x y) (values a b))) (list a b x y))) ⇒ (x y a b)
Each formals should be a formal arguments list as for a
let*-values is similar to
let-values, but the bindings are
performed sequentially from left to right, and the region of a binding
indicated by (formals expression) is that part of the
let*-values expression to the right of the binding. Thus the
second binding is done in an environment in which the first binding is
visible, and so on.
(let ((a 'a) (b 'b) (x 'x) (y 'y)) (let*-values (((a b) (values x y)) ((x y) (values a b))) (list a b x y))) ⇒ (x y x y)
This convenience form (from SRFI-8) is equivalent to:
(let-values ((formals expression)) body)
(receive a (values 1 2 3 4) (reverse a)) ⇒ (4 3 2 1) (receive (a b . c) (values 1 2 3 4) (list a b c)) ⇒ (1 2 (3 4)) (let ((a 'a) (b 'b) (x 'x) (y 'y)) (receive (a b) (values x y) (receive (x y) (values a b) (list a b x y)))) ⇒ (x y x y)
The values resulting from evaluating each argument are appended together.