Common Lisp the Language, 2nd Edition
The loop construct do (or doing) takes one or more expressions and simply evaluates them in order.
The loop construct return takes one expression and returns its value. It is equivalent to the clause do (return value).
The do construct simply evaluates the specified expressions wherever they occur in the expanded form of loop.
The expr argument can be any non-atomic Common Lisp form. Each expr is evaluated in every iteration.
The constructs do, initially, and finally are the only loop keywords that take an arbitrary number of forms and group them as if using an implicit progn. Because every loop clause must begin with a loop keyword, you would use the keyword do when no control action other than execution is required.
;;; Print some numbers. (loop for i from 1 to 5 do (print i)) `;Prints 5 lines 1 2 3 4 5 => NIL ;;; Print numbers and their squares. ;;; The DO construct applies to multiple forms. (loop for i from 1 to 4 do (print i) (print (* i i))) `;Prints 8 lines 1 1 2 4 3 9 4 16 => NIL
The return construct terminates a loop and returns the value of the specified expression as the value of the loop. This construct is similar to the Common Lisp special form return-from and the Common Lisp macro return.
The Loop Facility supports the return construct for backward compatibility with older loop implementations. The return construct returns immediately and does not execute any finally clause that is given.
;;; Signal an exceptional condition. (loop for item in '(1 2 3 a 4 5) when (not (numberp item)) return (cerror "enter new value" "non-numeric value: ~s" item)) `;Signals an error >>Error: non-numeric value: A ;;; The previous example is equivalent to the following one. (loop for item in '(1 2 3 a 4 5) when (not (numberp item)) do (return (cerror "enter new value" "non-numeric value: ~s" item))) `;Signals an error >>Error: non-numeric value: A