Chap 7: Iteration on Numbers and Lists
Do's: Dotimes, Dolist, Do
DOTIMES
-
count parameter: e.g. n
- upper-bound form is evaluated:
how many times to do dotimes
- result form: where dotimes puts result ... (else returns NIL)
n
m
(defun dotimes-expt (m n)
(let ((result 1)) ;initialize result
(dotimes (count n result)
(setf result (* m result))
)
)
)
Interesting - count parameter is not in body
in this example
DOLIST
-
list form: evaluated producing a list
- element parameter: elements - one at a time
- result form: same as before - if none, returns
NIL,
probably used for side effects
(output in PRINT may be what want)
*(count-outlyers '(18 75 31 180 270 52))
(setf freezing 32 boiling 212)
(defun count-outlyers (list-of-elements)
(let ((result 0))
(dolist (element list-of-elements result)
(when (or (> element boiling)
(< element freezing)
)
(setf result (+ result 1))
)
)
)
)
(counts : simpler to use COUNT-IF)
Whenever a
(RETURN )
is encountered in a DOLIST or DOTIMES,
the expression is evaluated and becomes
value of the function call (eg return the first n outlyers)
(defun first-n-outlyers (n list-of-elements)
(let ((result 0)(outlyers nil))
(dolist (element list-of-elements outlyers)
(cond ((or (> element boiling)
(< element freezing))
(setf result (+ result 1))
(push element outlyers)
)
((= n result)(return outlyers))
)
)
)
) ;filters
Typically, the purpose of DO's is for side-
effects, not the result
(defun clear-top (object)
(dolist (obstacle t)
(get-rid-of obstacle)
)
)
DO is more general
(like do-while...bindings interesting)
LOOP:
the forms in the body are evaluated
repeatedly ... until a
(return )
is found
*(setf cheers '(cheer cheer cheer))
*(setf loop-count 0)
*(loop
(when (endp cheers) (return loop-count))
(setf cheers (rest cheers))
(setf loop-count (+ loop-count 1)))
3
PROG1, PROGN
evaluate a series of forms sequentially but
return the value of only one
(rest are
evaluated for side-effects only)
DEFUN, LET, LET*, WHEN, and UNLESS do
this implicitly (i.e., return last form)
*(prog1 (setf a 'x) (setf b 'y) (setf c 'z))
a
*(progn (setf a 'x) (setf b 'y) (setf c 'z))
z
Since the bodies of DEFUN and LETs can
contain any number of forms, PROG1 and
PROGN are not used much