Subject: Re: Newbie cluelessness continued...
From: (Rob Warnock)
Date: Sun, 27 Apr 2003 06:43:53 -0500
Newsgroups: comp.lang.lisp
Message-ID: <>
Sascha Wilde  <> wrote:
| Sascha Wilde <> 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)))))


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		<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607