John Thingstad <john.thingstad@chello.no> wrote:
+---------------
| micromoog <micromoog@gmail.com> wrote:
| > Is LOOP the way to go, then, for iteration?
|
| Well. That is debatable.
| Some lispers avoid LOOP like the plaugue claiming it is unlispy.
| DO has a simple command structure that although difficult to read
| until you get used to it is far easier to get right.
| Now there is plenty of documentation on how to use LOOP right
| though so it is less of a problem.
| Still see www.norvig.com/luv-slides.ps for some style guides.
+---------------
Also, start slow with LOOP, sticking to a few simple templates
you understand [or useful idioms you see posted], and only add
additional refinements as you find you actually need them later.
A couple of my favorite basic LOOP-using functions [note the defaulting
of "FOR var = form" which LOOP treats as "FOR var = form THEN form"]:
(defun file-lines (path)
"Sucks up an entire file from PATH into a list of freshly-allocated
strings, returning two values: the list of strings and the number of
lines read."
(with-open-file (s path)
(loop for line = (read-line s nil nil)
while line
collect line into lines
counting t into line-count
finally (return (values lines line-count)))))
(defun file-forms (path)
"Sucks up an entire file from PATH into a list of forms (sexprs),
returning two values: the list of forms and the number of forms read."
(with-open-file (s path)
(loop with eof = (list :eof)
for form = (read s nil eof)
until (eq form eof)
collect form into forms
counting t into form-count
finally (return (values forms form-count)))))
The most common set of simple "scanning" iterators in LOOP:
- To scan a list, use "FOR item IN some-list ...".
- To scan a string, use "FOR char ACROSS some-string ..."
- To scan an alist, use "FOR (key . val) IN some-alist ..."
- To scan a property list, use "FOR (prop val) ON some-plist BY #'cddr ..."
- To scan a hash table, you need to type a somewhat longer template:
FOR key BEING HASH-KEY IN some-hash-table USING (HASH-VALUE value) ...
Examples:
> (let ((alist '((a . 5) (b . 3) (c . 17))))
(loop FOR (key . val) IN alist
do (format t "~a = ~s~%" key val)))
A = 5
B = 3
C = 17
NIL
> (let ((plist '(a 5 b 3 c 17)))
(loop FOR (prop val) ON plist BY #'cddr
do (format t "~a = ~s~%" prop val)))
A = 5
B = 3
C = 17
NIL
>
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607