Next: , Previous: FOR* Examples, Up: LOOP --> Loopless


2.4 Trivial Operators Examples

dotimes* is dotimes without an iteration variable. You might question the relevance of having such a minute variation on dotimes available. It comes down to a simple question of completeness. Loopless strives to always provide an unambiguous “best operator” in situations where loop has an answer and the rest of Common Lisp either doesn't provide an answer or provides a few different answers with no clear winner.

If dotimes* (and the maptimes* family of functions) didn't exist, each time I wanted to loop a certain number of times without caring for the iteration variable, I'd curse having to name the variable and be tempted to use loop for its repeat clause just this one time. I'm a really lazy programmer, and as far as possible, I don't want to have to think for recurring scenarios!

     (dotimes* (3 :done) (write-string "he"))
     ==
     (loop repeat 3 do (write-string "he"))
     -| hehehe
     ⇒ :DONE

Here's how to read forms from a stream with while*. This may not look much better than the loop way at first, but notice that each of collecting/collect, let, while* and setf does only one thing and can be used with the rest of the language.

Also, let and setf are conveniently already part of the language.

     (with-input-from-string (stream "some (simple \"forms\") #(to read)")
       (collecting
         (let (form)
           (while* (setf form (read stream nil nil))
             (collect form)))))
     ==
     (with-input-from-string (stream "some (simple \"forms\") #(to read)")
       (loop for form = (read stream nil nil)
             while form
             collect form))
     ⇒ (SOME (SIMPLE "forms") #(TO READ))