chapter 7 : Macros: Standard Control Constructs
when and unless
(if condition then-form [else-form])
the then-form and else-form are each restricted to being a single Lisp form
PROGN, executes any number of forms in order and returns the value of the last form
(if condition then-form [else-form]) then-form can be (progn then-form-one then-form-two)
to solve the problem ,using when macro which is a standard macro
using like this:
(when condition do-form)
(when (spam-p current-message)
(file-in-spam-folder current-message)
(update-spam-database current-message))
and when macro may be defined if it wasn’t built into the standard library
(defmacro when (condition &rest body)
`(if,condition (progn,@body)))
unless
(defmacro unless (condition &rest body)
`(if (not,condition) (progn,@body)))
cond macro
(cond
(test-1 form*)
(test-2 form*)
…
(test-N form*))
and ,or ,not
(not (= 2 3)) return T ,(not NIL) return T else return NIL
and or are macros
(and (or (= 1 2) (= 3 3)) (and (= 1 1) (= 2 2))) return T
looping
dolist dotimes
basic skeletion
(dolist (var list-form)
body-form*)
when the loop starts ,the list-form is evaluated once to produce a list
(dolist (x ‘(1 2 3)) (print x))
1
2
3
NIL
use return
(dolist (x ‘(1 2 3)) (print x) (if (evenp x) (return))) evenp if var is a even number
dotimes
(dotimes (var count-form)
body-form*)
(dotimes (i 4) (print i))
0
1
2
3
NIL
support nest loops
do
(do (variable-definition*)
(end-test-form result-form*)
statement*)
e.g
(do ((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
((= 10 n) cur)))
(defun foo (i)
(do ((n 0 (1+ n))
(cur 0 next)
(next 1 (+ cur next)))
((= i n) (list n cur next))))
what step-form do is assign a new value ,and it allows more than one parameter
the mighty loop
an infinite loop like
(loop
body-form*) it will iterate forever unless you use return to break out
(loop
(when (> (get-universal-time) * some-future-date*)
(return))
(format t “Waiting … ~%”)
(sleep 1))
(do ((nums nil) (i 1 (1+ i)))
((> i 10) (nreverse nums))
(push i nums)) -> (1 2 3 4 5 6 7 8 9 10)
(loop for i from 1 to 10 collecting i) -> (1 2 3 4 5 6 7 8 9 10)
(loop for x from 1 to 10 summing (expt x 2)) -> 385
(loop for i below 10
and a = 0 then b
and b = 1 then (+ b a)
finally (return a))
(loop for x across “the quick brown fox jumps over the lazy dog”
counting (find x “aeiou”))
the symbols across below collecting couting finally for from summing then to