Jonathan.Bailleul <bailleul@greyc.ismra.fr> wrote:
+---------------
| The do* formulation appeared first, but it becomes awkward since I have
| to supply the same (long) expression for variable initialisation and
| update.
...
| (with-open-file (stream (make-pathname :name input-file-name)
| :direction :input)
| (let ((acc (list)))
| (do* ((current-line (read-line stream nil 'eof)
| (read-line stream nil 'eof)))
| ((equal current-line 'eof) (nreverse acc))
| (push (str-tokenize current-line) acc)))))
+---------------
Others have shown you the standard idioms using LOOP, so I won't,
but will make a few small observations:
- You don't need DO* here; DO is enough.
- You don't need a separate LET; DO is enough.
- You don't need to call LIST to get an empty list; a constant will do.
- Since your EOF object is a symbol, your don't need EQUAL; EQ is enough.
- An idiom useful especially with DO[1] is to use #= & ## syntax when
repeating an long form.
Putting it all together, we get:
(with-open-file (stream input-file-name)
(do ((acc '())
(line #1=(read-line stream nil 'eof) #1#))
((eq line 'eof) (nreverse acc))
(push (str-tokenize line) acc)))
-Rob
[1] Note: This is not needed with LOOP's "for var = form", since it's
already implied. That is, "for var = form" has the same meaning as
"for var = #1=form then #1#".]
-----
Rob Warnock, PP-ASEL-IA <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607