The loop-finish
macro can be used lexically within
an extended
loop
form
to terminate that form “normally.”
That is, it transfers control to the loop epilogue
of the lexically innermost extended loop
form.
This permits execution of any finally
clause (for effect)
and
the return of
any accumulated result.
;; Terminate the loop, but return the accumulated count. (loop for i in '(1 2 3 stop-here 4 5 6) when (symbolp i) do (loop-finish) count i) → 3 ;; The preceding loop is equivalent to: (loop for i in '(1 2 3 stop-here 4 5 6) until (symbolp i) count i) → 3 ;; While LOOP-FINISH can be used can be used in a variety of ;; situations it is really most needed in a situation where a need ;; to exit is detected at other than the loop's `top level' ;; (where UNTIL or WHEN often work just as well), or where some ;; computation must occur between the point where a need to exit is ;; detected and the point where the exit actually occurs. For example: (defun tokenize-sentence (string) (macrolet ((add-word (wvar svar) `(when ,wvar (push (coerce (nreverse ,wvar) 'string) ,svar) (setq ,wvar nil)))) (loop with word = '() and sentence = '() and endpos = nil for i below (length string) do (let ((char (aref string i))) (case char (#\Space (add-word word sentence)) (#\. (setq endpos (1+ i)) (loop-finish)) (otherwise (push char word)))) finally (add-word word sentence) (return (values (nreverse sentence) endpos))))) → TOKENIZE-SENTENCE (tokenize-sentence "this is a sentence. this is another sentence.") → ("this" "is" "a" "sentence"), 19 (tokenize-sentence "this is a sentence") → ("this" "is" "a" "sentence"), NIL
Transfers control.
Whether or not loop-finish
is fbound in the
global environment is implementation-dependent;
however, the restrictions on redefinition and shadowing of
loop-finish
are the same as for symbols in the COMMON-LISP
package
which are fbound in the global environment.
The consequences of attempting to use loop-finish
outside
of loop
are undefined.
loop, Section 6.1 (The LOOP Facility)