Common Lisp the Language, 2nd Edition
Next: Dynamic Non-Local Exits
Up: Multiple Values
Previous: Constructs for Handling
It is often the case that the value
of a special form or macro call
is defined to be the value of one of its subforms.
For example, the
value of a cond is the value of the last form in the selected clause.
In most such cases, if the subform produces multiple values, then the original
form will also produce all of those values.
This passing back of
multiple values of course has no effect unless eventually one of the
special forms for receiving multiple values is reached.
To be explicit, multiple values can result from a special form
under precisely these circumstances:
Evaluation and application
-
eval returns multiple values if the form given it to
evaluate produces multiple values.
-
apply, funcall, and multiple-value-call
pass back multiple values from the function applied or called.
Implicit progn contexts
-
The special form progn
passes back multiple values resulting from evaluation of the
last subform. Other situations referred to as ``implicit progn,''
where several forms are evaluated and the results of all but the last form
are discarded, also pass back multiple values from the last form.
These situations include the body of a lambda-expression,
in particular those constructed by defun,
defmacro, and deftype.
Also included are bodies of the constructs
eval-when,
progv, let,
let*, when, unless,
block,
multiple-value-bind, and catch,
as well as clauses in such conditional
constructs as
case, typecase,
ecase, etypecase, ccase, and ctypecase.
X3J13 has voted to add many new constructs to the language that contain
implicit progn contexts. I won't attempt to list them all here.
Of particular interest, however, is locally, which may be regarded
as simply a version of progn that permits declarations before its
body. This provides a useful building block for constructing macros
that permit declarations (but not documentation strings)
before their bodies and pass back any multiple values
produced by the last sub-form of a body. (If a body can contain a documentation
string, most likely lambda is the correct building block to use.)
Conditional constructs
-
if passes back multiple values from whichever subform is selected
(the then form or the else form).
-
and and or pass back multiple values from the last subform
but not from subforms other than the last.
-
cond passes back multiple values from the last subform of
the implicit progn of the selected clause.
If, however, the clause selected is a singleton clause,
then only a single value (the non-nil predicate value)
is returned. This is true even if the singleton clause is
the last clause of the cond. It is not permitted to
treat a final clause (x) as being the same as (t x)
for this reason; the latter passes back multiple values from the form x.
Returning from a block
-
The block construct passes back multiple values from its last subform
when it exits normally. If return-from (or return) is
used to terminate the block prematurely, then return-from
passes back multiple values from its subform as the values of the
terminated block. Other constructs that create implicit blocks,
such as
do, dolist, dotimes, prog, and
prog*, also pass back multiple values specified by
return-from (or return).
-
do passes back multiple values from
the last form of the exit clause, exactly as if the exit clause
were a cond clause. Similarly, dolist and dotimes
pass back multiple values from the resultform if that is executed.
These situations are all examples of implicit uses of return-from.
Throwing out of a catch
-
The catch construct returns multiple values if
the result form in a throw exiting from
such a catch produces multiple values.
Miscellaneous situations
-
multiple-value-prog1 passes back multiple values from its first
subform. However, prog1 always returns a single value.
-
unwind-protect returns multiple values if the form it protects
returns multiple values.
-
the returns multiple values if the form it contains returns
multiple values.
Among special forms that never pass back multiple values are
prog1,
prog2, setq, and multiple-value-setq.
The conventional way to force only one value to be returned from a form x
is to write (values x).
The most important rule about multiple values is:
No matter how many values a form produces,
if the form is an argument form in a function call,
then exactly one value (the first one) is used.
For example, if you write (cons (floor x)), then cons will always
receive exactly one argument (which is of course an error),
even though floor returns two values. To pass both values from floor
to cons, one must write something like
(multiple-value-call #'cons (floor x)).
In an ordinary function call,
each argument form produces exactly one argument; if such a form
returns zero values, nil is used for the argument, and if more than one
value, all but the first are discarded.
Similarly, conditional constructs such as if that test the value of a form
will use exactly one value, the first one, from that form and discard the rest;
such constructs will use nil as the test value if zero values are returned.
Next: Dynamic Non-Local Exits
Up: Multiple Values
Previous: Constructs for Handling
AI.Repository@cs.cmu.edu