2.3 End-test control
until End-Test Control Clause Keyword
while
expr
until
expr
while
construct allows iteration to continue until the specified expression evaluates tonil
. The expression is reevaluated at the location of thewhile
clause.
until
construct is equivalent towhile
(not
expr)...
. If the value of the specified expression is non-nil
, iteration terminates.
while
anduntil
at any point in a loop. If awhile
oruntil
clause causes termination, any clauses that precede it in the source are still evaluated.
;; UNTIL NOT is equivalent to WHILE. > (loop until (not (hungry-p)) do (eat));; Collect the length and the items of STACK. > (let ((stack '(a b c d e f))) (loop while stack for item = (length stack) then (pop stack) collect item)) (6 A B C D E F)
;; Use WHILE to terminate a loop that otherwise wouldn't ;; terminate. ;; Note that WHILE occurs after the WHEN. > (loop for i fixnum from 3 when (oddp i) collect i while (< i 5)) (3 5)
always
, never
, thereis
never End-Test Control Clause Keyword
thereis End-Test Control Clause Keyword
always
expr
never
expr
thereis
expr
always
construct takes one form and terminates the loop if the form ever evaluates tonil
; in this case, it returnsnil
. Otherwise, it provides a default return value oft
.
never
construct takes one form and terminates the loop if the form ever evaluates to non-nil
; in this case, it returnsnil
. Otherwise, it provides a default return value oft
.
thereis
construct takes one form and terminates the loop if the form ever evaluates to non-nil
; in this case, it returns that value.
while
anduntil
constructs cause termination, control is passed to the loop epilogue, where anyfinally
clauses will be executed. Sincealways
,never
, andthereis
use the Common Lisp macroreturn
to terminate iteration, anyfinally
clause that is specified is not evaluated.
;; Make sure I is always less than 11 (two ways). ;; The FOR construct terminates these loops. > (loop for i from 0 to 10 always (< i 11)) T> (loop for i from 0 to 10 never (> i 11)) T
;; If I exceeds 10 return I; otherwise, return NIL. ;; The THEREIS construct terminates this loop. > (loop for i from 0 thereis (when (> i 10) i) ) 11
;;; The FINALLY clause is not evaluated in these examples. > (loop for i from 0 to 10 always (< i 9) finally (print "you won't see this")) NIL
> (loop never t finally (print "you won't see this")) NIL
> (loop thereis "Here is my value" finally (print "you won't see this")) "Here is my value"
;; The FOR construct terminates this loop, so the FINALLY clause ;; is evaluated. > (loop for i from 1 to 10 thereis (> i 11) finally (print i)) 11 NIL
;; If you could use this code to find a counterexample to ;; Fermat's ;; last theorem, it would still not return the value of the ;; counterexample because all of the THEREIS clauses in this example ;; only return T. Of course, this code does not terminate. > (loop for z upfrom 2 thereis (loop for n upfrom 3 below (log z 2) thereis (loop for x below z thereis (loop for y below z thereis (= (+ (expt x n) (expt y n)) (expt z n))))))
while
, until
loop-finish
loop-finish
terminates iteration normally and returns any accumulated result. If specified, afinally
clause is evaluated.
loop-finish
because other loop control clauses terminate the loop. Useloop-finish
to provide a normal exit from a nested condition inside a loop.
loop-finish
inside nested Lisp code to provide a normal exit from a loop. Sinceloop-finish
transfers control to the loop epilogue, usingloop-finish
within afinally
expression can cause infinite looping.
;; Print a date in February, but exclude leap year day. ;; LOOP-FINISH exits from the nested condition. > (loop for date in date-list do (case date (29 (when (eq month february) (loop-finish)) (format t ":@(~A) ~A" month date))));; 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
;; This loop works just as well as the previous example. > (loop for i in '(1 2 3 stop-here 4 5 6) until (symbolp i) count i) 3
Generated with Harlequin WebMaker