Multiple Values and Value Counts

Receive several return values, store them in a list, and find errors caused by the wrong value count.

Use call-with-values to receive several results from one call. You can pass them to another procedure as separate arguments or collect them in one list for storage.

Receive a quotient and remainder

Run each example on this page separately in the Playground.

LISPEX
(call-with-values (lambda () (floor/ 17 5)) list)

Result

OUTPUT
(3 2)

floor/ returns quotient 3 and remainder 2 as two values. call-with-values passes them as two arguments to list. list returns the single list (3 2), which you can store in a variable.

To calculate with the two results immediately, receive them in two parameters.

LISPEX
(call-with-values
  (lambda () (floor/ 17 5))
  (lambda (q r) (+ (* q 5) r)))

Result

OUTPUT
17

call-with-values calls the first procedure, the producer, with no arguments. It passes every returned value to the second procedure, the consumer. The consumer must accept that argument count or the call reports E302. A rest parameter, which collects extra arguments, counts toward what the consumer can accept.

Where one value is required

A value context is a place in an expression with a rule for how many values it accepts. An ordinary call argument needs exactly one value. So do an if condition, a variable initializer, and the right-hand side of set! or define.

LISPEX
(+ (values 1 2) 3)

Diagnostic

OUTPUT
E320

The first argument to + produced two values where one was required. Returning zero values with (values) in that position also reports E320. It supplies no placeholder value.

Each argument to values must itself produce one value. These arguments are evaluated from left to right. Thus (values (values 1 2) 3) also reports E320.

Where other counts are accepted

Before the final expression in a body or begin, results are discarded. Those positions accept any value count. The producer of call-with-values can also return any count, provided the consumer accepts it.

ExpressionResultWhy
(+ (values 1) 2)3values returns exactly one value
(begin (values 1 2) 3)3The first expression's two values are discarded
(call-with-values (lambda () (values)) list)()list receives zero arguments and returns one empty list
(call-with-values (lambda () (values 1 2)) list)(1 2)list receives two arguments and returns one list

Store several results as one value

Multiple return values form a value packet, which is passed to the next computation. To store the results, construct a list or vector. For example, (list 1 2) creates one value containing two elements. Passing that list to a two-parameter consumer supplies only one argument and causes E302.

The multiple-values guide shows a complete example that stores a list. See procedures for argument-count rules.