Sascha Wilde <swilde@sha-bang.de> wrote:
+---------------
| Sascha Wilde <swilde@sha-bang.de> wrote:
| > ...i would prefer using do rather when loop...
| > (defun read-file (arg-file-name)
| > (with-open-file (stream arg-file-name :direction :input)
| > (do ((line nil (read-line stream nil stream))
| > (r nil (push line r)))
| > ((eql line stream) (cdr (nreverse r))))))
|
| Having a second look on what I wrote, I think it might be not correct,
| for the binding of r depends on line.
+---------------
Not only that, but you're completely wasting the first pass through
the loop! [And thus pushing a redundant NIL on the result list, which
you have to get rid of later.]
+---------------
| So I think do* would be the right way:
|
| (do* ((line nil (read-line stream nil stream))
| (r nil (push line r)))
| ((eql line stream) (nreverse (cdr r))))))
+---------------
Again, still wasting the first pass through the loop. The way I always
used to code it [before turning to the dark side and learning to love LOOP]
was to use #=/## to duplicate the READ-LINE form, and also use a simple
CONS instead of PUSH (since you're NREVERSEing anyway -- but with no CDR):
(defun read-file (arg-file-name)
(with-open-file (stream arg-file-name :direction :input)
(do ((line #1=(read-line stream nil nil) #1#)
(result nil (cons line result)))
((not line) (nreverse result)))))
-Rob
p.s. I conventionally use NIL as the EOF marker with READ-LINE or
READ-CHAR since it's faster to test [and can't be returned by them],
reserving "stream" or some other unique constant [such as a read-time
gensym] for use with READ. Others prefer to use the same code pattern
all the time, to save thinking about it. As usual, YMMV...
-----
Rob Warnock, PP-ASEL-IA <rpw3@rpw3.org>
627 26th Avenue <URL:http://rpw3.org/>
San Mateo, CA 94403 (650)572-2607