[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Unexpected READ-FROM-STRING behavior

cornell@freya.cs.umass.edu writes:
> Am I loosing my mind? I'm getting behavior from READ-FROM-STRING that
> seems wrong. It concerns the optional :start argument, which I'm
> passing but doesn't seem to be having much effect.

No, you're not losing your mind.  A keyword argument that appears to be
a ketword argument is not always a keyword - particularly when a function
supports optional and keyword arguments, like read-from-string. If you
want to use keyword arguments, you'll have to supply all of the optional

> Consider the following three tests in mcl2.0:
    ? (let ((string "(a 23 b)"))
        (read-from-string string :start 0))
    (A 23 B)                            ; right
--->   Wrong, this is equivalent to
       (let ((string "(a 23 b)"))
	(read-from-string string t 0))  ; generate error on eof and set
					; eof-value to 0.
    ? (let ((string "(a 23 b)"))
        (read-from-string string :start 1))
    (A 23 B)                            ; huh!? should be returning A, right?
--->   Wrong, this is equivalent to
       (let ((string "(a 23 b)"))
	(read-from-string string t 1))   ; interpretation similar to above
    ? (let ((string "(a 23 b)"))
        (read-from-string (subseq string 1 (length string))))
    A                                   ; expected this result in second case

Detailed Answer:  The "problem" occurs because the read-from-string function
	 has two optional and keyword arguments. In the first two
	 examples above the keyword and its argument are interpreted as
	 the two optional arguments.  This is probably an FAQ on Mark
	 Kantorwitz's FAQ list.

Here is the specification of the read-from-string function:
    read-from-string string &optional eof-error-p eof-value &key
        :start :end :preserve-whitespace

In the first two examples:
    (read-from-string string :start 0))
    (read-from-string string :start 1))

eof-error-p is :start and eof-value is 0 in the first case 
and 1 in the second case.

Here are examples that show that this interpretation is correct:
(let ((string ""))
  ? (read-from-string "" nil 0)    ; suppress the eof error and return 0 
  ? (read-from-string "" t 0)      ; signal an error
  > Error: Unexpected end of file encountered.
  > While executing: CCL::%READ-FORM