values - return multiple values
LIBRARY
(import (rnrs)) ;R6RS
(import (rnrs base)) ;R6RS
(import (scheme r5rs)) ;R7RS
(import (scheme base)) ;R7RS
SYNOPSIS
(values obj ...)
DESCRIPTION
Delivers all of its arguments to its continuation. The
values
procedure might be defined as follows:
(define (values . things)
(call-with-current-continuation
(lambda (cont) (apply cont things))))
The continuations of all non-final expressions within a sequence of
expressions, such as in
lambda,
begin,
let,
let*,
letrec,
letrec*,
let-values,
let*-values,
case, and
cond
forms,
usually take an arbitrary number of values (but see the note on
compatibility). Except for these and the continuations created by
call-with-values,
let-values, and
let*-values, and
define-values,
continuations implicitly accepting a single value, such as the continuations
of
operator and operands
of procedure calls or the
test
expressions in conditionals, take exactly one value. The effect of
passing an inappropriate number of values to such a continuation is
undefined.
This feature implements true multiple return values. On the language
level it works more in the way that Golang does it and less like how
tuples or lists are used to simulate this feature in languages like
Python and JavaScript.
IMPLEMENTATION NOTES
Implementations vary greatly in how they treat multiple values that
are returned to single-value continuations. Portable programs should
not rely on any of these behaviors.
- Chez Scheme
-
Single-value continuations verify that they receive a single value and
otherwise raise an exception.
Note however that the source optimizer utilizes the underspecification
of what happens when multiple values are returned to single-value
continuations. An example is that (let ((x (values 1 2))) x) is
optimized to (values 1 2).
- Chibi Scheme
-
Multiple values are represented as a list where the car is (values).
- GNU Guile
-
Single-value continuations that receive multiple values use the first
value. Single-value continuations that receive zero values raise
an exception.
- Ikarus Scheme
-
Single-value continuations verify that they receive a single value and
otherwise raise an exception.
- IronScheme
-
Single-value continuations that receive zero or multiple values receive
an object that represents those values.
- Larceny Scheme
-
Single-value continuations that receive multiple values use the first
value. Single-value continuations that receive zero values receive
the unspecified value.
- Loko Scheme
-
Single-value continuations that receive multiple values use the first
value. Single-value continuations that receive zero values receive
a void value.
- Racket
-
Single-value continuations verify that they receive a single value and
otherwise raise an exception.
- Sagittarius
-
Single-value continuations that receive multiple values use the first
value. Single-value continuations that receive zero values receive
the unspecified value.
- Vicare Scheme
-
A type checker verifies that the right number of values are returned.
In particular, it raises a
&syntax
error if two branches if an
if
return different numbers of values.
RETURN VALUES
Returns the values given as arguments.
EXAMPLES
(let-values (((a b) (values 1 2))
((c d) (values 3 4)))
(list a b c d))
=> (1 2 3 4)
(define (quotient+remainder n d)
(let ((q (quotient n d)))
(values q (- n (* q d)))))
(quotient+remainder 10 3)
=> 3
=> 1
((lambda (x) x) (values 1 2)) => unspecified
APPLICATION USAGE
This procedure is often combined with syntax to receive the values,
such as
let-values(3scm).
Another option is
receive
from SRFI-8, which only binds a single set of values.
RATIONALE
- R6RS Rationale
-
Many computations conceptually return several results.
Scheme expressions implementing such computations can return the
results as several values using the values procedure. Of course, such
expressions could alternatively return the results as a single
compound value, such as a list, vector, or a record. However, values
in programs usually represent conceptual wholes; in many cases,
multiple results yielded by a computation lack this coherence.
Moreover, this would be inefficient in many implementations, and a
compiler would need to perform significant optimization to remove the
boxing and unboxing inherent in packaging multiple results into a
single values. Most importantly, the mechanism for multiple values in
Scheme establishes a standard policy for returning several results
from an expression, which makes constructing interfaces and using them
easier.
[It then goes on to discuss the contentious issue of what should
happen when the wrong number of values is passed to a continuation.]
COMPATIBILITY
This procedure is compatible across all Schemes that support it as long
as the continuation accepts the given number of values.
R5RS contains the following language, which is not in R6RS and R7RS:
Except for continuations created by the call-with-values procedure,
all continuations take exactly one value.
ERRORS
This procedure can raise exceptions with the following condition types:
- &assertion (R6RS)
-
The wrong number of values was passed to a continuation set up with
call-with-values.
- R7RS
-
Returning the wrong number of values to a continuation
not created by
call-with-values,
and which is not the non-final expression of a sequence,
is unspecified and implementation-dependent.
SEE ALSO
apply(3scm),
let-values(3scm),
call-with-values(3scm)
STANDARDS
R5RS,
R6RS,
R7RS
HISTORY
First appeared in R5RS. The R4RS formal semantics notes:
The reason that expression continuations take sequences
of values instead of single values is to simplify the formal
treatment of procedure calls and to make it easy to add
multiple return values.
AUTHORS
This page is part of the
scheme-manpages
project.
It includes materials from the RnRS documents.
More information can be found at
https://github.com/schemedoc/manpages/
.
Markup created by unroff 1.0sc, March 04, 2023.