User Tools



  • read &optional input-stream eof-error-p eof-value recursive-pobject
  • read-preserving-whitespace &optional input-stream eof-error-p eof-value recursive-pobject

Arguments and Values


read parses the printed representation of an object from input-stream and builds such an object.

read-preserving-whitespace is like read but preserves any whitespace character that delimits the printed representation of the object.

read-preserving-whitespace is exactly like read when the recursive-p argument to read-preserving-whitespace is true.

When *read-suppress* is false, read throws away the delimiting character required by certain printed representations if it is a whitespace character; but read preserves the character (using unread-char) if it is syntactically meaningful, because it could be the start of the next expression.

If a file ends in a symbol or a number immediately followed by an end of file, read reads the symbol or number successfully; when called again, it sees the end of file and only then acts according to eof-error-p. If a file contains ignorable text at the end, such as blank lines and comments, read does not consider it to end in the middle of an object.

If recursive-p is true, the call to read is expected to be made from within some function that itself has been called from read or from a similar input function, rather than from the top level.

Both functions return the object read from input-stream. Eof-value is returned if eof-error-p is false and end of file is reached before the beginning of an object.





(with-input-from-string (is " ") (read is nil 'the-end))


;;; TODO the following example is broken, fix it (defun skip-then-read-char (s c n) (if (char= c #\{) (read s t nil t) (read-preserving-whitespace s)) (read-char-no-hang s))


(let ((*readtable* (copy-readtable nil))) (set-dispatch-macro-character #\# #\{ #'skip-then-read-char) (set-dispatch-macro-character #\# #\} #'skip-then-read-char) (with-input-from-string (is "#{123 x #}123 y") (format t "~S ~S" (read is) (read is))))

#\\x, #\\Space, NIL

As an example, consider this reader macro definition:

(defun slash-reader (stream char) (declare (ignore char)) `(path . ,(loop for dir = (read-preserving-whitespace stream t nil t) then (progn (read-char stream t nil t) (read-preserving-whitespace stream t nil t)) collect dir while (eql (peek-char nil stream nil nil t) #\\/))))


(set-macro-character #\/ #'slash-reader)


Consider now calling read on this expression:

(zyedh /usr/games/zork /usr/games/boggle)

The / macro reads objects separated by more / characters; thus /usr/games/zork is intended to read as (path usr games zork). The entire example expression should therefore be read as

(zyedh (path usr games zork) (path usr games boggle))

However, if read had been used instead of read-preserving-whitespace, then after the reading of the symbol zork, the following space would be discarded; the next call to peek-char would see the following /, and the loop would continue, producing this interpretation:

(zyedh (path usr games zork usr games boggle))

There are times when whitespace should be discarded. If a command interpreter takes single-character commands, but occasionally reads an object then if the whitespace after a symbol is not discarded it might be interpreted as a command some time later after the symbol had been read.

Affected By

Exceptional Situations

read signals an error of type end-of-file, regardless of eof-error-p, if the file ends in the middle of an object representation. For example, if a file does not contain enough right parentheses to balance the left parentheses in it, read signals an error. This is detected when read or read-preserving-whitespace is called with recursive-p and eof-error-p non-nil, and end-of-file is reached before the beginning of an object.

If eof-error-p is true, an error of type end-of-file is signaled at the end of file.

See Also