Multiple Values and Value Contexts

Multiple values are an evaluation outcome, never a storable guest value. Every continuation position declares how many values it accepts.

When this matters

Use multiple values when one computation naturally produces several coordinated results and immediately hands them to a known consumer. Use a list or vector instead when the group must be stored as data.

See it run

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

Observed result

OUTPUT
(3 2)

Read the example

floor/ produces quotient 3 and remainder 2 as two values. call-with-values passes them as two arguments to list, which deliberately turns the transient packet into the storable list (3 2).

How to reason about it

  • Single-value contexts require exactly one value and raise E320 for zero or at least two.
  • Discard contexts accept any count; call-with-values passes the producer packet as consumer arguments.
  • The operands of values are themselves single-value contexts evaluated left to right.

Choose quickly

ContextAccepted countExample
ordinary operand or binding initializerexactly one(+ (values 1) 2)
begin before the final formany count, discarded(begin (values 1 2) 3)
producer of call-with-valuesany count(lambda () (values 1 2))
consumer of call-with-valuesmust accept produced arity(lambda (a b) ...)
stored aggregateone list/vector value(list 1 2)

A common mistake

Multiple values are not boxed into a list or vector.

Current boundaries

  • Using (values) where one value is required is an error, not an unspecified sentinel.

Keep going

The practical guide builds a producer and consumer. Procedure arity explains the consumer-side failure.

Multiple-values guide · Procedures and arity