views:

109

answers:

3

This is the code to implement the 'cat' command with lisp, as is explained in the book ANSI Common Lisp, page 122.

(defun pseudo-cat (file)
  (with-open-file (str file :direction :input)
    (do ((line (read-line str nil 'eof)
               (read-line str nil 'eof)))
        ((eql line 'eof))
      (format t "~A~%" line))))

Why is the read-line function read twice? I tried to run it with only one read-line, but the Lisp couldn't finish the code.

A: 

You can use (listen file) for test if you can read from the file.

This is my print-file function

(defun print-file (filename)
  "Print file on stdout."
  (with-open-file (file filename :direction :input)
          (loop
             (when (not (listen file)) (return))
             (write-line (read-line file)))))
jcubic
multiple concats and using format to create new strings is really wasteful. Don't do that.
Rainer Joswig
That's a wrong approach since it will produce wrong results. E.g. if you pass the name of named pipe in linux or windows, it will probably not be immediatelly ready for input, hence listen will return NIL and function will return without actually copying anything.
dmitry_vk
+9  A: 

The syntax of DO variables is: variable, initialization form, update form. In this case, the initialization form is the same as the update form. But there is no shorthand for that case in DO, so you have to write it out twice.

Xach
+4  A: 

You need to read the syntax of DO: http://www.lispworks.com/documentation/HyperSpec/Body/m_do_do.htm

The first READ-LINE form is the init-form and the second is the step-form. So in the first iteration the variable is set to the result of the init-form. In the next iterations the variable is set to the value of the step-form.

Rainer Joswig
+1 for providing a link
Donal Fellows