loop-finish
loop-finish ⟨no arguments⟩ →
The loop-finish macro can be used lexically within KMP changed it to say extended
aan extended loop form to terminate that form “normally.” That is, it transfers control to the loop epilogue Added per X3J13 -kmp 05-Oct-93of the lexically innermost extended loop form. This permits execution of any finally clause (for effect) and Per X3J13. -kmp 05-Oct-93
then returnsthe return of any accumulated result.
Clarified above per X3J13. -kmp 05-Oct-93 KMP added this because it was implicitly vague and portable programs must know this fact to avoid utter lossage. It affects nesting behavior, as explained in a note farther down. -kmp 1-Aug-93 It is \term{implementation-defined} whether \macref{loop-finish} can be used in a simple \macref{loop} form.
;; 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.
None.
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)
Semantics clarified per X3J13. -kmp 05-Oct-93
This part added to make it clear to users that this is a portability pitfall. Because it is \term{implementation-defined} whether \macref{loop-finish} will work in a simple \macref{loop} form, it follows an obvious consequence that a form such as the following is not portable: \code (loop (loop-finish)) \endcode However, what may be less obvious is that there are implications on nesting behavior as well. In particular, it is recommended that user code not mix styles (simple and extended) of \macref{loop} forms when \macref{loop-finish} will be involved. For example, the following form is also not portable: \code (loop do (loop (loop-finish))) \endcode