Chapter 3 - Essential Lisp in Twelve Lessons

Lesson 9 - Essential Multiple Values

Most forms create only one value

A form typically returns only one value. Lisp has only a small number of forms which create or receive multiple values.

VALUES creates multiple (or no) values

The VALUES form creates zero or more values:

? (values)

? (values :this)
-> :THIS

? (values :this :that)
-> :THIS
-> :THAT

We show how many values are returned by the number of -> lines produced by the evaluation of the form. The three VALUES forms in the example above produced zero, one, and two values, respectively.

VALUES is a function, and so evaluates its arguments.

A few special forms receive multiple values

What might you want to do with multiple values in a program? The most basic operations are to:

  1. bind each value to a separate symbol, or
  2. collect the values into a list.

Use MULTIPLE-VALUE-BIND to bind each value to a separate symbol:

? (multiple-value-bind (a b c) (values 2 3 5)
(+ a b c))
-> 10

If you provide more values than symbols, the excess values are ignored:

? (multiple-value-bind (a b c) (values 2 3 5 'x 'y)
(+ a b c))
-> 10

If you provide fewer values than symbols, the excess symbols are bound to NIL:

? (multiple-value-bind (w x y z) (values :left :right)
(list w x y z))
-> (:LEFT :RIGHT NIL NIL)

Some forms pass along multiple values

Some forms pass along the last value in their body, rather than creating a new value. Examples include the bodies of LET, COND, DEFUN, and LAMBDA.

? (let ((a 1)
(b 2))
(values a b))
-> 1
-> 2

? (cond (nil 97)
(t (values 3 4)))
-> 3
-> 4

? (defun foo (p q)
(values (list :p p) (list :q q)))
-> FOO

? (foo 5 6)
-> (:P 5)
-> (:Q 6)

? ((lambda (r s)
(values r s))
7 8)
-> 7
-> 8

In the case of the function and lambda bodies, the multiple values are actually returned by something called an "implicit PROGN." This is a fancy way of saying that the bodies can contain multiple forms, and only the value of the last form is returned.

You can use the PROGN special form when you want this behavior. (PROGN form1 form2 ... formN) evaluates form1 through formN in order, and returns the value of formN.


Contents | Cover
Chapter 2 | Chapter 3, Introduction | Chapter 3, Lesson 8 | Chapter 3, Lesson 9 | Chapter 3, Lesson 10 | Chapter 4 |

Copyright © 1995-2001, David B. Lamkins
All Rights Reserved Worldwide

This book may not be reproduced without the written consent of its author. Online distribution is restricted to the author's site.