# Common Lisp Loops

I can’t think why you wouldn’t use the Common Lisp loop macro in Emacs. Don’t forget to (require ‘cl-lib)

### Simple Loops

``````;; keywords: to, upto, below, downto, above, by
;; keywords: collect, append, nconc, count, sum, maximize, minimize

(cl-loop
do (princ 1))
=> 111111... infinite loop

(cl-loop repeat 5
do (princ 1)
(princ 2))
=> 1212121212

(cl-loop for i from 1 below 10
maximize i)
=> 9

(cl-loop for x from 9 downto 1
collect x)
=> (9 8 7 6 5 4 3 2 1)

(cl-loop for i from 10 above 1 by 2
collect i)
=> (10 8 6 4 2)``````

### Looping over Sets and Arrays

``````;; keywords: in, on, across, by
;; Remember in for lists
;; across for vectors

(cl-loop for l in '(1 2 3 4 5)
do (princ l))
=> 12345

(cl-loop for l in '(1 2 3 4 5) by #'cddr
collect l)
=> (1 3 5)

(cl-loop for l on '(1 2 3 4 5)
collect l)
=> ((1 2 3 4 5) (2 3 4 5) (3 4 5) (4 5) (5))

(cl-loop for l on '(1 2 3 4 5) by #'cddr
collect l)
=> ((1 2 3 4 5) (3 4 5) (5))

;; Remember that a string is an array in lisp, so...
;; Add up the digits in 90125
(cl-loop for d across "90125"
sum (- d 48))
=> 17``````

### Destructuring

``````(cl-loop for (a nil) in '((1 2) (2 3) (3 4))
collect a)
=> (1 2 3)

(cl-loop for (a b) in '((1 2) (2 3) (3 4))
collect (* a b))
=> (2 6 12)

(cl-loop for (a b) on '(1 2 3 4 5) while b
collect (+ a b))
=> (3 5 7 9)

(cl-loop for (a b) on '(1 2 3 4 5) by #'cddr while b
collect (+ a b))
=> (3 7)``````

### Hashtables

``````(cl-loop for key being the hash-keys of myhashtable
using (hash-value value)
do (princ value))``````

### Parallel fors

``````(cl-loop for i from 1 to 5
for l in '(a b c d)
collect (list i l))
=> ((1 a) (2 b) (3 c) (4 d))

(cl-loop for i from 1 to 5
for j from 2 to 10 by 2
collect (* i j))
=> (2 8 18 32 50)``````

### Nested fors

``````(cl-loop for i from 1 to 5
collect (cl-loop for j from 1 to 5
collect (* i j)))
=> ((1 2 3 4 5) (2 4 6 8 10) (3 6 9 12 15) (4 8 12 16 20) (5 10 15 20 25))

(cl-loop for i from 1 to 5
append (cl-loop for j from 1 to 5
collect (* i j)))
=> (1 2 3 4 5 2 4 6 8 10 3 6 ...)

(cl-loop for i from 1 to 5
collect (cl-loop for j from 1 to 5
sum (* i j)))
=> (15 30 45 60 75)

(cl-loop for i from 1 to 5
sum (cl-loop for j from 1 to 5
sum (* i j)))
=> 225``````

### Selection

``````;; if, when, unless

(cl-loop for i from 1 to 20
unless (cl-evenp i) collect i)
=> (1 3 5 7 9 11 13 15 17 19)

(cl-loop for i from 1 to 20
when (= (% i 3) 0) collect i into fizz
when (= (% i 5) 0) collect i into buzz
finally return (list fizz buzz))
=> ((3 6 9 12 15 18) (5 10 15 20))

(cl-loop for i from 1 to 20
if (and (= (% i 3) 0) (= (% i 5) 0)) collect i into fizzbuzz
else if (= (% i 3) 0) collect i into fizz
else if (= (% i 5) 0) collect i into buzz
finally return (list fizz buzz fizzbuzz))
=> ((3 6 9 12 18) (5 10 20) (15))

(cl-loop for i from 1 to 10
if (cl-evenp i)
collect i into evens
and sum i into evensum
else
collect i into odds
and sum i into oddsum
finally return (list evens evensum odds oddsum))
=> ((2 4 6 8 10) 30 (1 3 5 7 9) 25)

Find c from comp where diff is never a member of squares
(cl-loop for c in comp
if  (cl-loop for p in pri
for diff = (/ (- c p) 2)
never (member diff squares))
collect c)``````

### Then Iteration

``````(cl-loop for i from 1 to 5
for square = (* i i)
collect square)

;; Though you'd be better with
(cl-loop for i from 1 to 5
collect (* i i))

;; However, this leads to Triangle Numbers
(cl-loop for n from 1 to 10
for triangle = 1 then (+ triangle n)
collect triangle)
=> (1 3 6 10 15 21 28 36 45 55)

(cl-loop for x = 0 then y
for y = 1 then (+ x y)
while (< y 30)
collect y)
=> (1 2 4 8 16)

;; Fibonacci Sequence (note the and)
(cl-loop for x = 0 then y
and y = 1 then (+ x y)
while (< y 30)
collect y)
=> (1 1 2 3 5 8 13 21)``````

### Termination

``````;; while, until, always, never, and thereis

while and until are straightforward

(cl-loop for n from 1
for tri = 1 then (+ tri n)
until (> (divs tri) 500)
finally return tri)

never, thereis and always are shorthand for a combination of when-return

(defun isprime(n)
(cond
((< n 2) nil)
((= n 2) t)
((cl-evenp n) nil)
(t
(cl-loop for i from 3 to (sqrt n) by 2
never (= (% n i) 0)))))``````

This site uses Akismet to reduce spam. Learn how your comment data is processed.