I can’t think why you wouldn’t use the Common Lisp loop macro in Emacs. [Don't forget to (require 'cl-lib)](https://www.emacswiki.org/emacs/CommonLispForEmacs) ### Simple Loops ```lisp ;; 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 ```lisp ;; 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 ```lisp (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 ```lisp (cl-loop for key being the hash-keys of myhashtable using (hash-value value) do (princ value)) ``` ### Parallel fors ```lisp (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 ```lisp (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 ```lisp ;; 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 ```lisp (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 ```lisp ;; 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))))) ```