At its core, Scheme's evaluation semantics is multiplevalue based. Continuations can accept an arbitrary number of values and expressions can yield an arbitrary number of values. This is in contrast to the functional languages ML and Haskell." (Marc NieperWißkirchen, SRFI 210)
History:

R5RS introduced multiplevalue returns, supported with the
values
andcallwithvalues
syntax. 
R6RS added the
letvalues
andlet*values
forms, previously defined in SRFI 11. 
R7RS has added
definevalues
.
R7RSsmall contains the following five constructs dealing with multiple values:

callwithvalues
 used to pass values returned from a producer procedure to a consumer 
definevalues
 used likedefine
, but binds values to identifiers 
letvalues
 used likelet
, but binds values to identifiers 
let*values
 used likelet*
, but binds values to identifiers with an environment covering the previous bindings 
values
 bundles its arguments together as a set of values
What are "multiple values"? As the name suggests, they are representations of
more than one value  but they are bound together. This binding is not the
same as some kind of data structure, like a list
. Notice the following:
gosh$ (values 1 2) <1> 1 2
 This creates multiple values from the values 1 and 2.
As a more useful example, (scheme base)
contains the procedure
exactintegersqrt
. The definition for this states: "Returns two nonnegative
exact integers s and r".
gosh$ (exactintegersqrt 16) 4 0 gosh$ (exactintegersqrt 17) 4 1
How can we get and use all of the returned values?
This is where the define
and let
forms come in.
definevalues
works like define
but matches up a series of identifiers
with the respective returned value:
gosh$ (definevalues (root remainder) (exactintegersqrt 17)) remainder gosh$ root 4 gosh$ remainder 1
As definevalues
is matching a list of formals (like lambda
), it is easy to
get values as lists, etc:
gosh$ (definevalues vals (values 1 2 3)) vals gosh$ vals (1 2 3) gosh$ (list? vals) #t gosh$ (definevalues (head . rest) (values 1 2 3)) rest gosh$ head 1 gosh$ rest (2 3)
There are no surprises with letvalues
and let*values
: these work
in the same way as let
and let*
, but use multiple identifiers to
match multiple values:
(define (findroots x y) (letvalues (((xroot xremainder) (exactintegersqrt x)) ; <1> ((yroot yremainder) (exactintegersqrt y))) (list xroot yroot))) ; <2>
 Collect and name the multiple values
 Return some in a list
And with let*values
:
(define (roots+totalremainder x y) (let*values (((xroot xremainder) (exactintegersqrt x)) ((yroot yremainder) (exactintegersqrt y)) ((roots totalremainder) (values (list xroot yroot) ; <1> (+ xremainder yremainder)))) (list roots totalremainder)))

It's a
let*
form, so we can access the previous definitions.
The remaining form, callwithvalues
, ties together the production and
consumption of multiple values: a producer is a zeroargument procedure that
returns multiple values, using a values
expression, and a consumer is a
procedure that accepts these values as its arguments.
Notice the little "gotcha" that the producer must be a zeroargument procedure.
(define (showroot n) (callwithvalues (lambda () (exactintegersqrt n)) ; <1> (lambda (s r) (display (square s)) ; <2> (display " + ") (display r) (newline)))) gosh$ (showroot 15) 9 + 6
 The producer procedure, returns two values.
 The consumer procedure accepts those two values as its arguments.
Two SRFIs, SRFI 8 and SRFI 210, are particularly targetted at multiple values: these have both been accepted into the Yellow Edition of R7RSlarge.
This SRFI appears in several other SRFIs, its single definition often copypasted into the reference implementation of other libraries.
The SRFI provides the receive
syntax, to improve on callwithvalues
.
Specifically, instead of having a zeroargument procedure as producer,
receive
accepts any expression as a producer, and its values are bound
into a set of provided identifiers. These can then be processed within
the expression's body.
The showroot
example above can be rewritten to use receive
as:
(define (showroot n) (receive (s r) (exactintegersqrt n) ; <1> (display (square s)) ; <2> (display " + ") (display r) (newline)))
 The multiplereturn values are captured into the given identifiers.
 The body can work with those identifiers.
Of course, in a postR5RS world, we have letvalues
as an alternative,
which also has the advantage of being able to "receive" values from
multiple producers. The above example using letvalues
:
(define (showroot n) (letvalues (((s r) (exactintegersqrt n))) ; <1> (display (square s)) ; <2> (display " + ") (display r) (newline)))
 The multiplereturn values are captured into the given identifiers.
 The body can work with those identifiers.
Aimed at introducing procedures and syntax for dealing with multiple values, such as creating lists and vectors from expressions returning multiple values and procedures returning the elements of a list or vector as multiple values.
This SRFI introduces a number of syntactic forms and procedures. I have divided these into separate groups, with related functionality, but not explained every construct.
 Definition
(coarity producer)
 Description

producer
 an expression producing multiple values
Evaluates producer
and returns the number of resulting values.
 Example
gosh[r7rs.user]$ (coarity 3) 1 gosh[r7rs.user]$ (coarity (values 1 2 3)) 3 gosh[r7rs.user]$ (coarity (exactintegersqrt 11)) 2
 Definition
(set!values formals producer)
 Description

formals
 a formal arguments list 
producer
 an expression producing multiple values
Evaluates producer
and assigns its multiple values to identifiers
in the formal arguments list. It has the same relation to set!
as
definevalues
does to define
.
 Example
gosh[r7rs.user]$ (define x 2) x gosh[r7rs.user]$ (define y 3) y gosh[r7rs.user]$ (set!values (x y) (exactintegersqrt 11)) 2 gosh[r7rs.user]$ x 3 gosh[r7rs.user]$ y 2
 Definition
(value index value1 ...) + (value/mv index value1 ... [producer])
 Description

index
 a positive integer 
value1
 an expression 
producer
 an optional expression producing multiple values
Evaluates one or more values and returns the index
position value.
For value/mv
, the last expression can produce multiple values.
 Error
If index
is out of range, or a multiplevalues producer is in any but the
last position.
 Example
gosh[r7rs.user]$ (value 1 'a 'b 'c) <1> b gosh[r7rs.user]$ (value/mv 1 'a 'b 'c) b gosh[r7rs.user]$ (value/mv 2 'a 'b (values 'c 'd)) <2> c gosh[r7rs.user]$ (value 2 'a 'b (values 'c 'd)) c gosh[r7rs.user]$ (value 3 'a 'b (values 'c 'd)) <3> *** ERROR: argument out of range: 3 gosh[r7rs.user]$ (value/mv 3 'a 'b (values 'c 'd)) d gosh[r7rs.user]$ (value/mv 1 'a (values 'b 'c) 'd) <4> *** ERROR: received more values than expected
 Both work with single value expressions to return the indexed value.

Using
values
can work like a single value. 
But the
value/mv
form can use the values as part of the indexed range. 
For
value/mv
, any producer must be in the last position.
 Definition
(casereceive producer clause1 ...)
 Description

producer
 an expression producing multiple values 
clause1
 each clause is of form (formals body)
A matching clause is found, matching formals
in each clause against
the values returned by the producer, as done in lambda
. And then
the body
of that matching clause is evaluated, in the context of
any bindings introduced by the match.
 Example
We could adapt exactintegersqrt
so it returns a single value if the
remainder is 0:
(define (neweis n) (letvalues (((s r) (exactintegersqrt n))) (if (zero? r) s (values s r))))
And then write a function to choose how to display the number:
(define (displayroot n) (casereceive (neweis n) ((s) (display "Exact root: ") (display s) (newline)) ((s r) (display "Inexact, with remainder: ") (display r) (newline)))) gosh[r7rs.user]$ (displayroot 3) Inexact, with remainder: 2 gosh[r7rs.user]$ (displayroot 4) Exact root: 2
The identity
procedure is equivalent to values
.
 Definition
(list/mv value1 ... [producer])
 Description

value1
 an expression 
producer
 an optional expression producing multiple values
Evaluates one or more values and producer, returning all the values as a list.
 Error
If a multiplevalues producer is in any but the last position.
 Example
gosh[r7rs.user]$ (list/mv (values 'a 'b 'c)) (a b c) gosh[r7rs.user]$ (list/mv 'a 'b 'c) (a b c) gosh[r7rs.user]$ (list/mv 'a 'b 'c (values 'd 'e)) (a b c d e) gosh[r7rs.user]$ (list/mv 'a 'b 'c (values 'd 'e) 'f) *** ERROR: received more values than expected
There are also natural extensions for vector and (srfi 195) box types, as
vector/mv
and box/mv
.
 Definition
(listvalues listitems)
 Description

listitems
 a list of values
Returns the given list of values as multiple values.
 Error
If listitems
is not a list.
There are also natural extensions for vector and (srfi 195) box types, as
vectorvalues
and boxvalues
.
 Definition
(apply/mv procedure value1 ... [producer])
 Description

procedure
 a positive integer 
value1
 an expression 
producer
 an optional expression producing multiple values
Evaluates one or more values and an optional producer, and then applies the given procedure to the values.
 Error
If a multiplevalues producer is in any but the last position.
 Example
gosh[r7rs.user]$ (apply/mv string #\a #\b) "ab" gosh[r7rs.user]$ (apply/mv string #\a #\b (values #\c #\d)) "abcd" gosh[r7rs.user]$ (string #\a #\b #\c #\d) <1> "abcd"
 The previous example is the same as this procedure application.
 Definition
(call/mv consumer producer1 ...)
 Description

consumer
 a procedure that will be called on the values returned from the producers 
producer1
 one or more expressions producing multiple values
Evaluates the procedures, collecting their multiple values together, and then applies the consumer on the values.
 Example
We can use this to convert multiple values into a list or vector:
gosh[r7rs.user]$ (call/mv list (exactintegersqrt 26)) (5 1) gosh[r7rs.user]$ (call/mv vector (exactintegersqrt 26) (exactintegersqrt 3)) #(5 1 1 2)
 Definition
(mapvalues procedure)
 Description

procedure
 a procedure accepting and returning a single value
Returns a procedure which accepts an arbitrary number of arguments. When
applied, it applies the given procedure
to each of the arguments, returning
the results as multiple values.
 Example
gosh[r7rs.user]$ ((mapvalues exactintegersqrt) 3 26) 1 5
 Definition
(withvalues producer consumer)
 Description

producer
 an expression which returns multiple values 
consumer
 a procedure accepting the values from the producer
The producer
and consumer
are evaluated, and the procedure resulting
from evaluating the consumer is applied to the values results from
evaluating the producer.
This is like callwithvalues
except the producer is simply evaluated, not
called.
 Example
Rewriting our earlier showroot
procedure shows the difference:
(define (showroot n) (withvalues (exactintegersqrt n) ; <1> (lambda (s r) (display (square s)) ; <2> (display " + ") (display r) (newline)))) gosh$ (showroot 15) 9 + 6
 The producer returns two values.
 The consumer procedure accepts those two values as its arguments.
 Definition
(bind/mv producer procedure1 ...)
 Description

producer
 an expression producing multiple values 
procedure1
 each procedure accepts the values from the preceding procedure, and returns multiple values
Chains a series of procedures together, passing multiple values between them.
 Example
bind/mv
can be used as a simple form of procedure composition, where multiple
values returned from one part are passed on to the next procedure in the line:
gosh[r7rs.user]$ (define (displaypair s r) (display s) (display " + ") (display r) (newline)) <1> displaypair gosh[r7rs.user]$ (bind/mv 13 exactintegersqrt displaypair) 3 + 4
 Define a procedure which takes two values and displays them.
There are also forms specialised for producers of different datatypes:

bind/list
 uses a list as the produced values 
bind/box
 likebind/list
but for a (srfi 195) box. 
bind
 likebind/list
but for any object.
 Definition
(composeleft procedure1 ...)
 Description

procedure1
 the procedures should accept an appropriate number
of arguments and return multiple values so the chain is well formed.
Constructs a leftcomposition of its arguments, so that:
((composeleft f g h) args) # is equivalent to # (apply/mv h (apply/mv g (apply f args)))
 Examples
composeleft
is not much different to normal function composition.
For example, we could compose the odd?
and not
functions together
to make a notodd
function:
gosh[r7rs.user]$ (define notodd (composeleft odd? not)) notodd gosh[r7rs.user]$ (notodd 3) #f gosh[r7rs.user]$ (notodd 4) #t
The difference is that composeleft
internally uses apply/mv
to apply the
second procedure to the first: hence the first procedure can return multiple
values, which the second one can then use. The following example composes the
multiplevalue returning exactintegersqrt
with a procedure to display the
two values:
gosh[r7rs.user]$ (define (displaypair s r) (display s) (display " + ") (display r) (newline)) <1> displaypair gosh[r7rs.user]$ (define displaysqrt (composeleft exactintegersqrt displaypair)) <2> displaysqrt gosh[r7rs.user]$ (displaysqrt 3) 1 + 2
 Define a procedure which takes two values and displays them.

Now compose this with
exactintegersqrt
, which returns multiple values.
 Definition
(composeright procedure1 ...)
 Description

procedure1
 the procedures should accept an appropriate number
of arguments and return multiple values so the chain is well formed.
Constructs a rightcomposition of its arguments, so that:
((composeright f g h) args) # is equivalent to # (apply/mv f (apply/mv g (apply h args)))
 Examples
composeright
is the same as composeleft
, but with the order of arguments
reversed. The following example composes the multiplevalue returning
exactintegersqrt
with a procedure to display the two values:
gosh[r7rs.user]$ (define displaysqrt (composeright displaypair exactintegersqrt)) displaysqrt gosh[r7rs.user]$ (displaysqrt 3) 1 + 2
Different Schemes handle multiple values in some contexts in different ways.
For example, Gauche permits multiplevalues to be used in singlevalue contexts:
gosh$ (+ (values 1 2) (values 3 4)) <1> 4 gosh$ (map (lambda (a) (values a a)) '(1 2 3)) (1 2 3)
 Notice how adding two sets of multiple values together only deals with the first value in each pair of values.
But this is not required behaviour, and indeed the R7RS report states that, for map
, it is an
error if the mapped procedure does not return a single value.
Chez Scheme gives errors in both cases:
Chez Scheme Version 9.5.8 Copyright 19842022 Cisco Systems, Inc. > (+ (values 1 2) (values 3 4)) Exception: returned two values to single value return context > (map (lambda (a) (values a a)) '(1 2 3)) Exception: returned two values to single value return context
Kawa only gives an error in the first case, but not the second:
#kawa:1# (+ (values 1 2) (values 3 4)) java.lang.ClassCastException: class gnu.mapping.Values$Values2 cannot be cast to class gnu.math.Numeric #kawa:2# (map (lambda (a) (values a a)) '(1 2 3)) (1 1 2 2 3 3)