Producing and Consuming Multiple Values

Use `values` to return a value packet and `call-with-values` to connect that packet to a consumer with matching arity.

See it run

LISPEX
(call-with-values (lambda () (values 3 4)) (lambda (a b) (+ (* a a) (* b b))))

Observed result

OUTPUT
25

Walk through the pattern

  1. Produce the packet. The first lambda returns two values, 3 and 4; it does not construct a list.
  2. Match the consumer. The second lambda has two parameters, so its arity matches the packet exactly.
  3. Compute normally. Inside the consumer, a and b are ordinary single values and the final arithmetic returns 25.

How to reason about it

  • Place the producer in the dedicated producer context, not in a call operand, test, binding initializer, or assignment RHS.
  • The consumer receives each produced value as one argument and is arity-checked normally.
  • Use (values) deliberately for zero values in discard-capable control paths.

Check yourself

Replace the consumer with list. What result is stored, and why is that different from the producer packet?

Answer

The result is the ordinary list (3 4). call-with-values passed two arguments, and list deliberately constructed one storable value.

A common mistake

Do not encode semantic multiple values as an ordinary list when the caller expects value arity.

Keep going

The manual defines every value context. Procedure arity explains what happens when the consumer expects the wrong count.

Multiple-value contexts · Procedures and arity