Would you mind to explain me the meaning of a RECURSIVE-P argument of
READ-* functions in more detail ?
For example, suppose I'm going to write my own function that parses
stream. What things I should care about ? If RECURSIVE-P is true I
should read only those characters that belong to printed
representation of my object. Trailing whitespace I should UNREAD-CHAR.
Is it true ? If RECURSIVE-P is NIL I should not bother returning
trailing whitespace to stream. Are there some other things concerning
RECURSIVE-P I should be aware of ?
Another question.
In CLHS (Function READ, READ-PRESERVING-WHITESPACE) I could read
READ-PRESERVING-WHITESPACE is like READ but preserves any
whitespace[2] 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.
Is this correct ? Should not it sound like "READ-PRESERVING-WHITESPACE
is exactly like READ when the RECURSIVE-P argument to
READ is true." ?
What READ-PRESERVING-WHITESPACE would do when RECURSIVE-P is NIL ? I'd
guess that READ and READ-PRESERVING-WHITESPACE differ only in their
defaults to RECURSIVE-P but this seems not very probable.
--
Vladimir Zolotykh
In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
> Another question.
>
> In CLHS (Function READ, READ-PRESERVING-WHITESPACE) I could read
>
> READ-PRESERVING-WHITESPACE is like READ but preserves any
> whitespace[2] 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.
>
> Is this correct ? Should not it sound like "READ-PRESERVING-WHITESPACE
> is exactly like READ when the RECURSIVE-P argument to
> READ is true." ?
It seems that CLISP does it your way; it makes a recursive-p READ behave like
READ-PRESERVING-WHITESPACE, rather than vice versa.
;; recursive read-preserving-whitespace
(with-input-from-string (s "foo bar")
(read-preserving-whitespace s t t t) (read-char s)) ==> #\Space
;; non-recursive read-preserving-whitespace
(with-input-from-string (s "foo bar")
(read-preserving-whitespace s t t nil) (read-char s)) ==> #\Space
;; recursive read
(with-input-from-string (s "foo bar")
(read s t t t) (read-char s)) ==> #\Space
;; non-recursive read
(with-input-from-string (s "foo bar")
(read s t t nil) (read-char s)) ==> #\b
On Sat, 27 Jul 2002 16:09:56 +0000 (UTC), Kaz Kylheku <···@ashi.footprints.net>
wrote:
>In article <·················@eurocom.od.ua>, Vladimir Zolotykh wrote:
>> Another question.
>>
>> In CLHS (Function READ, READ-PRESERVING-WHITESPACE) I could read
>>
>> READ-PRESERVING-WHITESPACE is like READ but preserves any
>> whitespace[2] 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.
>>
>> Is this correct ? Should not it sound like "READ-PRESERVING-WHITESPACE
>> is exactly like READ when the RECURSIVE-P argument to
>> READ is true." ?
This has my vote for "Most Opaque Passage in the Hyperspec." Part of
the confusion stems from recursive-p controlling two different
behaviors: preserving of whitespace and #n# / #n= processing.
This is the deal:
READ-PRESERVING-WHITESPACE always preserves whitespace. READ preserves
whitespace if RECURSIVE-P is t, otherwise it does not.
Both READ and READ-PRESERVING-WHITESPACE establish a new "context" for
#n# / #n= when recursive-p is nil; otherwise they use the existing
context.
So, the passage in the Hyperspec is literally correct but not very helpful.
>
>It seems that CLISP does it your way; it makes a recursive-p READ behave like
>READ-PRESERVING-WHITESPACE, rather than vice versa.
How can you tell? vice-versa is the same thing ;-)
Here's read from CMUCL. Not authoritative, of course, but
illustrative:
(defun read (&optional (stream *standard-input*) (eof-errorp t)
(eof-value ()) (recursivep ()))
"Reads in the next object in the stream, which defaults to
*standard-input*. For details see the I/O chapter of
the manual."
(prog1
(read-preserving-whitespace stream eof-errorp eof-value recursivep)
(let ((whitechar (read-char stream nil eof-object)))
(if (and (not (eofp whitechar))
(or (not (whitespacep whitechar))
recursivep))
(unread-char whitechar stream)))))
Tim