Subject: Re: lisp idiom for processing each line in a file?
From: (Rob Warnock)
Date: Mon, 20 Feb 2006 04:20:16 -0600
Newsgroups: comp.lang.lisp
Message-ID: <>
<> wrote:
| I'm trying to process each line in a file, and am wondering if there is
| a simpler or more idiomatic way of doing it than the following:
| ;;; Simplified version of my real process-line function
| (defun process-line (line)
|   (format t "~A~%" line))
| ;;; Process stream, calling per-line-fn on each line of the stream
| (defun process (per-line-fn stream)
|   (let ((line (read-line stream nil)))
|     (if (not (null line))
|         (progn (funcall per-line-fn line)
|                (process per-line-fn stream)))))

This can blow up if your file is large and your CL implementation
doesn't happen to perform tail-call optimization on the tail call
to PROCESS.   Note: Common Lisp is not Scheme.

| And I kick off the process like so:
| CL-USER> (with-open-file (stream "../../words/test.txt")
| 	   (process #'process-line stream))

The standard CL idiom omits the intermediate PROCESS function
entirely, and does the whole thing in the WITH-OPEN-FILE call:

    (with-open-file (stream "../../words/test.txt")
      (loop for line = (read-line stream nil nil)
	    while line do
	(per-line-fn line)))

| Is there a simpler way of doing what I'm trying to do here?

See above.

| I've seen some loop-based solutions, but am staying away from
| loop for the moment.

Why?!? It's the most natural way to code this particular task, IMHO.

You don't have to use the entire repertoire of LOOP all at once.
Just pick a few simple idiomatic templates [such as the above]
and add more refinements as you discover you really need them.

Of course, you can also use DO, but to my taste it's a good deal

    (with-open-file (stream "../../words/test.txt")
      (do ((line #1=(read-line stream nil nil) #1#))
	  ((null line))
	(per-line-fn line)))


Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607