Pascal Costanza <pc@p-cos.net> wrote:
+---------------
| The general structure of a DO form is this:
|
| (do ((var1 init1 expr1)
| (var2 init2 expr2)
| ...)
| (predicate [result])
| body ...)
|
| This is equivalent to the following LOOP form:
|
| (loop for var1 = init1 then expr1
| for var2 = init2 then expr2
| ...
| until predicate
| ; or:
| when predicate return result
| do body ...)
|
| There is no real difference...
+---------------
Incorrect. These two are actually *semantically* different!!
To make them the same, you need to use AND instead of all but
the first FOR:
(loop for var1 = init1 then expr1
AND var2 = init2 then expr2
...
when predicate return result
do body ...)
Alternatively, you could have used your "all FORs" version
of the LOOP but replaced DO by DO*, then they would have also
been the same [but still different from the other DO/LOOP pair].
+---------------
| Compare:
| (loop for var1 in list1
| for var2 = init2 then expr2
| for index from 0
| do body ...)
|
| with:
| (do ((tail1 list1 (cdr tail1))
| (var2 init2 expr2)
| (index 0 (1+ index))
| ((null tail1))
| (let ((var1 (car tail1)))
| body ...))
+---------------
Again these are different: You need to either (1) use DO* for the
second or (2) in the LOOP replace all FOR except the first with AND.
Warning: (1) & (2) can give different results, depending upon the
form EXPR2!!
+---------------
| Really, there is no reason not to switch to LOOP when you usually use DO.
+---------------
I agree!! But when you do, at least get the semantics right... ;-} ;-}
-Rob
-----
Rob Warnock <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607