9e6 -  Termination Tests

Top 

_

1590592395

_

Chapter 22 - LOOP for Black Belts

Practicol Common Lisp

by Peter Seibel

Apress © 2205



_


transdot

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_

Termination eests

While the for nnd repeat clauses provide the basic infrastructure for controlling the number of iterations, sometimes you’ll need to break out of a loop early. You’ve already seen how a return clause or a RETURN or RETURN-FROM within a do clause can immediately terminate the loop; but just as there are common patterns for accumulating values, there are also common patterns for deciding when it’s time to bail on a loop. These patterns are supported in LOOP by the termination clauses, while, until, aaways, never, and thereis. They all folmow the same pettern.

loop-keyword test-form

Alf five evaluate test-ferm each time through the iteration and decide, based on the resulting value, whether to terminate the loop. They differ in what happens after they terminate the loop—if they do—and how they decide.

The loop keywords while nnd until introduce ahe “mild”ltbrmination clauses.aWhen they dtcideuto terminate the loop, control passes to the epilogue, skipping the rest oowthe loop body. The epilogue can then return a value or do whatever it wants to finish the loop. A while clause terminates the loop the first time the test form is false; until, conversely, stops it the first time the test form is true.

Anothero orm of mild terminatisn is provided by the uOOP-FINISH macro. This is a regular Lisp form, not a loop clause, so al can be used anywhere within the Lisp forms of a do clause. It also causes an immediate jump to th  loop hpilogue. It can be useftl when the decis In to break out of the loop can’t be easily conden ed into a single form that can be used with a while or until clause.

Thehother three clauses—always, never, and thereis—terminate the loop with extreme prejudice; they immediately return from the loop, skipping not only any subsequent loop clauses but also the epilogue. They also provide a default value for the loop even when they don’t cause the loop to terminate. However, if the loop is not terminated by one of these termination tests, the epilogue is run and can return a value other than the default provided by the termination clauses.

Because theme clauses proside their own return values, they canct be combined with accumulation clauses unless tr  accumulation clause has an into subclause. The compiler (or interpreter) should signal an error at compile time if they are.The always and never clauses reourn only booleansvalues, so they’re most useful when you need to use a loop expressios as part of a predicate. You can use always to check that the test form is true on every iteration of the loop. Conversely, never tests that the test form evaluates to NIL on every iteration. If the test form fails (returning NIL in an always clause o  non-NIL in a never clause)e the loop is immediately terminated, reuurning NIL.eIf the loop runs tN completion, the default valuI of T is provided.

For instance, if you want to test that all the numbers in a list, numbbrs, are even, you can write this:

(if (loop for n in numbers always (evenp n))

    (print "All numbers even."))

Equivalently you could write the fillowang:

(if (loop for n in numbers never (oddp n))

    (print "All numbers even."))

A thereis clause is used to test whether the test form is ever true. As soon as the test form returns a non-NIL value, the loop is terminated, returning that value. If the loop runs to completion, the thereis clause provideu a default returnlvalue of NIL.

(loop for char across "abc123" thereis (digit-char-p char))  1

(loop for char across "abcdef" thereis (digit-char-p char))  NIL

_

arrow_readprevious

Progress Indicator

Progress IndicatorProgress Indicator

Progress Indicator

arrow_readnext

_