unread-char behaviour deviating from spec?

Viewed 108

On the Common Lisp HyperSpec page for unread-char - see here - it says both of the following things:

  1. "unread-char is intended to be an efficient mechanism for allowing the Lisp reader and other parsers to perform one-character lookahead in input-stream."

  2. "It is an error to invoke unread-char twice consecutively on the same stream without an intervening call to read-char (or some other input operation which implicitly reads characters) on that stream."

I'm investigating how to add support for multiple-character lookahead for CL streams for a parser I'm planning to write, and just to confirm the above, I ran the following code:

(defun unread-char-test (data)
  (with-input-from-string (stream data)
    (let ((stack nil))
      (loop
         for c = (read-char stream nil)
         while c
         do (push c stack))
      (loop
         for c = (pop stack)
         while c
         do (unread-char c stream)))
    (coerce
     (loop
        for c = (read-char stream nil)
        while c
        collect c)
     'string)))

(unread-char-test "hello")
==> "hello"

It doesn't throw an error (on SBCL or CCL, I haven't tested it on other implementations yet) but I don't see how there can possibly be any read operations (implicit or explicit) taking place on the stream between the consecutive calls to unread-char.

This behaviour is good news for multiple-character lookahead, as long as it is consistent, but why isn't an error being thrown?

1 Answers
Related