From: Rusty Shackleford
Subject: collect inside loop not working right
Date: 
Message-ID: <slrnd2p9ac.aqb.rs@mwilson.umlcoop.net>
I want a list of all values found in one field in a fixed-position flat
file I'm reading in.  I hoped the following code below would return the
list, but it doesn't return squat.  What am I doing wrong?

    (with-open-file
     (s "top10lines.txt")
     (loop for line = (read-line s nil 'eof)
           until (eql line 'eof)
           for diag1 = (subseq line 156 160)
           for h-a = (subseq line 263 264)
           do (format t "diag1: ~A h-a: ~A admission: ~A.~%" diag1 h-a (equalp h-a "1"))
           collect diag1))

TIA

From: Harald Hanche-Olsen
Subject: Re: collect inside loop not working right
Date: 
Message-ID: <pcod5ub5gsm.fsf@shuttle.math.ntnu.no>
+ Rusty Shackleford <··@natchie.mine.nu>:

| I hoped the following code below would return the
| list, but it doesn't return squat.  What am I doing wrong?
| 
|     (with-open-file
|      (s "top10lines.txt")
|      (loop for line = (read-line s nil 'eof)
|            until (eql line 'eof)
|            for diag1 = (subseq line 156 160)
|            for h-a = (subseq line 263 264)
|            do (format t "diag1: ~A h-a: ~A admission: ~A.~%"
|                       diag1 h-a (equalp h-a "1"))
|            collect diag1))

It works for me on CMUCL, but it is not strictly correct.
According to the formal LOOP syntax, each variable-clause (such as
for) is supposed to come before every main-clause (which include
termination tests, such as until).  Try this instead:

(with-open-file
    (s "top10lines.txt")
  (loop with diag1 and h-a
     for line = (read-line s nil)
     while line
     do
       (setf diag1 (subseq line 156 160))
       (setf h-a (subseq line 263 264))
       (format t "diag1: ~A h-a: ~A admission: ~A.~%"
	       diag1 h-a (equalp h-a "1"))
     collect diag1))


(As an aside, I don't know why READ-LINE has the eof-value argument at
all, since nil is always safe.  Maybe it's for for compatibility with
READ, which does need this argument.)

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- Debating gives most of us much more psychological satisfaction
  than thinking does: but it deprives us of whatever chance there is
  of getting closer to the truth.  -- C.P. Snow
From: Joerg Hoehle
Subject: Re: collect inside loop not working right
Date: 
Message-ID: <ubr99j9fs.fsf@users.sourceforge.net>
Harald Hanche-Olsen <······@math.ntnu.no> writes:
> + Rusty Shackleford <··@natchie.mine.nu>:
> |     (with-open-file
> |      (s "top10lines.txt")
> |      (loop for line = (read-line s nil 'eof)
> |            until (eql line 'eof)
> |            for diag1 = (subseq line 156 160)
> |            for h-a = (subseq line 263 264)
> |            do (format t "diag1: ~A h-a: ~A admission: ~A.~%"
> |                       diag1 h-a (equalp h-a "1"))
> |            collect diag1))

> It works for me on CMUCL, but it is not strictly correct.
> According to the formal LOOP syntax, each variable-clause (such as
> for) is supposed to come before every main-clause (which include
> termination tests, such as until).

That's a common pitfall with LOOP. The Iterate package (from Jonathan
Amsterdam) is not affected by this restriction. Using Iterate, you
could write:

(iterate (for line in-file "top10lines.txt" :using #'read-line)
	 (for diag1 = (subseq line 156 160))
	 (for h-a   = (subseq line 263 264))
	 (format t "..."...)
	 (collect diag1))

>(subseq line 263 264)
Wouldn't you want to use (char line 263) instead and obtain a
character object instead of a string of length one?
Then use (CHAR= h-a #\1) or even EQL for tests?

Regards,
	Jorg Hohle
Telekom/T-Systems Technology Center
From: Marco Antoniotti
Subject: Re: collect inside loop not working right
Date: 
Message-ID: <JhkXd.44$fp1.65623@typhoon.nyu.edu>
Rusty Shackleford wrote:
> I want a list of all values found in one field in a fixed-position flat
> file I'm reading in.  I hoped the following code below would return the
> list, but it doesn't return squat.  What am I doing wrong?
> 
>     (with-open-file
>      (s "top10lines.txt")
>      (loop for line = (read-line s nil 'eof)
>            until (eql line 'eof)
>            for diag1 = (subseq line 156 160)
>            for h-a = (subseq line 263 264)
>            do (format t "diag1: ~A h-a: ~A admission: ~A.~%" diag1 h-a (equalp h-a "1"))
>            collect diag1))

Have you checked your lines?  I mean, are you sure they are longer that 
264 characters?


Cheers
--
Marco