(defmacro do-stream ((var stream &key (using '#'read)) &body body) (let ((s (gensym "STREAM")) (r (gensym "READER")) (done (gensym "DONE"))) `(loop :with ,s = ,stream :with ,r = ,using :for ,var = (funcall ,r ,s nil ',done) :until (eq ',done ,var) :do (progn ,@body)))) (with-open-file (f "foo.txt") (do-stream (line f :using #'read-line) (print line)))