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

Re: read-line



Regardless of the possible simplicity of fixing the read-line
problem, the I/O system is most definitely not quite fine.  Refer to
section 3.2 of the Kyoto Common Lisp Report for the details.

What is true is that the I/O system is sufficiently good for
non-interactive programs, and for many interactive ones (see, for
instance, the editor described in Yuasa and Hagiya's book on Common
Lisp).  To get the final details right requires, in general, code
that is not portable among various versions of Unix.  So it is quite
understandable that the authors preferred to leave this for later,
instead of taking time off from intellectually more productive parts
of the implementation.

What I had in mind in my previous message is similar to what
happened to GNU Emacs.  People who wanted it to work right in Sys V
and in VMS did the work, instead of trying to pass the problem to
the original author.  I don't expect asynchronous I/O to work the
same in BSD and System V, so we have a similar problem here.

Let's not permit our admiration for KCl make us blind to the places
where it can stand some work, especially if it depends on
peculiarities of operating systems.

Now, to the fix of toplevel.  The proposed solution is:

| Just change all calls to read in the toplevel to
| read-preserving-whitespace, then follow it with a read-line to
| throw away the newline.

Note that this solution is still not enough.  The read-line is
needed only if the next character is a #\Newline.  To determine it
you need a non-blocking version of {read,peek}-char, which is
precisely what is missing.  To understand the difference between
these two approaches, consider:

      >(dotimes (i 5) (format t ": ~s~%" (read)))
      1
      : 1
      2 3
      : 2
      : 3
      4 5 6
      : 4
      : 5
      nil

      >6

This is about what the toplevel does nowadays.  Observe that some of
the lines I typed contained more than one expression.  In
particular, the extra 6 got queued and correctly read later.  Of
course, some application might prefer that this queuing be flushed;
and that is something the Common Lisp provides, but KCl does not
implement.  Now, this is an abstraction of the proposed solution:

      >(dotimes (i 5) (format t ": ~s~%" (prog1 (read-preserving-whitespace)
                                                (read-line))))
      1
      : 1
      2 3
      : 2
      4 5 6
      : 4
      :lose
      : :lose
      'badly
      : 'badly
      nil

Valid input is being thrown away.

The important thing is not to decide whether the toplevel should
queue type-ahead or not.  The thing is that Common Lisp assumes that
each application can make an informed decision, but KCl does not
support one of the legal options.

See my next article for another (unsatisfactory) solution.

Cesar