Книга: Practical Common Lisp
Function Return Values
Function Return Values
All the functions you've written so far have used the default behavior of returning the value of the last expression evaluated as their own return value. This is the most common way to return a value from a function.
However, sometimes it's convenient to be able to return from the middle of a function such as when you want to break out of nested control constructs. In such cases you can use the RETURN-FROM
special operator to immediately return any value from the function.
You'll see in Chapter 20 that RETURN-FROM
is actually not tied to functions at all; it's used to return from a block of code defined with the BLOCK
special operator. However, DEFUN
automatically wraps the whole function body in a block with the same name as the function. So, evaluating a RETURN-FROM
with the name of the function and the value you want to return will cause the function to immediately exit with that value. RETURN-FROM
is a special operator whose first "argument" is the name of the block from which to return. This name isn't evaluated and thus isn't quoted.
The following function uses nested loops to find the first pair of numbers, each less than 10, whose product is greater than the argument, and it uses RETURN-FROM
to return the pair as soon as it finds it:
(defun foo (n)
(dotimes (i 10)
(dotimes (j 10)
(when (> (* i j) n)
(return-from foo (list i j))))))
Admittedly, having to specify the name of the function you're returning from is a bit of a pain—for one thing, if you change the function's name, you'll need to change the name used in the RETURN-FROM
as well.[61] But it's also the case that explicit RETURN-FROM
s are used much less frequently in Lisp than return
statements in C-derived languages, because all Lisp expressions, including control constructs such as loops and conditionals, evaluate to a value. So it's not much of a problem in practice.