User Tools

====== Local Macro LOOP-FINISH ====== ====Syntax==== * **loop-finish** ====Description==== The **loop-finish** macro can be used lexically within an extended **[[CL:Macros:loop]]** //[[CL:Glossary:form]]// to terminate that //[[CL:Glossary:form]]// "normally." That is, it transfers control to the loop epilogue of the lexically innermost extended **[[CL:Macros:loop]]** //[[CL:Glossary:form]]//. This permits execution of any **[[CL:Macros:finally]]** clause (for effect) and the return of any accumulated result. ====Examples==== The below example terminates the loop, but returns the accumulated count. <blockquote> (loop for i in '(1 2 3 stop-here 4 5 6) when ([[CL:Functions:symbolp]] i) do (loop-finish) count i) → 3 </blockquote> This loop is equivalent to: <blockquote> (loop for i in '(1 2 3 stop-here 4 5 6) until ([[CL:Functions:symbolp]] i) count i) → 3 </blockquote> 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: <blockquote> ([[CL:Macros:defun]] tokenize-sentence (string) ([[CL:Special Operators:macrolet]] ((add-word (wvar svar) `([[CL:Macros:when]] ,wvar ([[CL:Macros:push]] ([[CL:Functions:coerce]] ([[CL:Functions:nreverse]] ,wvar) '[[CL:Types:string]]) ,svar) ([[CL:Macros:setf]] ,wvar [[CL:Constant Variables:nil]])))) (loop with word = '() and sentence = '() and endpos = [[CL:Constant Variables:nil]] for i below ([[CL:Functions:length]] string) do ([[CL:Special Operators:let]] ((char ([[CL:Functions:aref]] string i))) ([[CL:Macros:case]] char (#\Space (add-word word sentence)) (#\. ([[CL:Macros:setf]] endpos ([[CL:Functions:math-one-plus|1+]] i)) (loop-finish)) (otherwise ([[CL:Functions:push]] char word)))) finally (add-word word sentence) ([[CL:Macros:return]] ([[CL:Functions:values]] ([[CL:Functions:nreverse]] sentence) endpos))))) <r>TOKENIZE-SENTENCE</r> (tokenize-sentence "this is a sentence. this is another sentence.") <r>("this" "is" "a" "sentence") 19</r> (tokenize-sentence "this is a sentence") <r>("this" "is" "a" "sentence") NIL</r> </blockquote> ====Side Effects==== Transfers control. ====Affected By==== None. ====Exceptional Situations==== Whether or not **loop-finish** is //[[CL:Glossary:fbound]]// in the //[[CL:Glossary:global environment]]// is //[[CL:Glossary:implementation-dependent]]//; however, the restrictions on redefinition and //[[CL:Glossary:shadow|shadowing]]// of **loop-finish** are the same as for //[[CL:Glossary:symbol|symbols]]// in the **COMMON-LISP** //[[CL:Glossary:package]]// which are //[[CL:Glossary:fbound]]// in the //[[CL:Glossary:global environment]]//. The consequences of attempting to use **loop-finish** outside of **[[CL:Macros:loop]]** are undefined. ====See Also==== * **[[CL:Macros:loop|Macro LOOP]]** * {\secref\LoopFacility} ====Notes==== \issue{LEXICAL-CONSTRUCT-GLOBAL-DEFINITION:UNDEFINED}