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

I/O proposal

	Just a few comments:

1.	Having a way to detect the end of file is needed, beyond that,
both alternatives (eof? or *eof*) can be trivially implemented on top
of the other.  I don't feel strongly about either, but I tend to agree
with Kent Dybvig since I view *eof* as more flexible.  If the other
option (eof?) is chosen, I would much rather have the name be
eof-object? .

2.	I disagree that the programmer should not be able to change
the current i/o streams. The debugging problem can be trivially fixed
if the error system/debugger always installs the appropriate stream,
and this can be accomplished easily by appropriate
with-input-from-stream and with-output-from-stream.

	Note that allowing the programmer to change them allows for a
cheap implementation of trasncript-on and transcript-off if the stream
objects are appropriately powerful (which they probably want to be).

	There is good reason for making them functions rather thatn
variables.  If they are variables, the implementation cannot easily
cash the internal components of a stream object in the appropriate
places.  For example, for faster default output the implementation can
cash in the printer the procedures for printing characters and strings
to the current output-stream.  If the variable is changed, the cash
has to be updated which means either that changes to some variables
are noticed (some variables are special, which I think is a bad idea),
or that the printer must check every time it is invoked.  Since
with-output-from..., etc, provide ways of redirecting output, and
furthermore, a procedure set-current-output-stream! can be provided,
there is no functionality lost and the implementation has more freedom.

3.	Having functions rather than special forms is in general good,
especially since we have not decided whether special form (and macro)
names are scoped in the same environment or in a different one, and
other such issues.

	Note that these functions parallel
call-with-current-continuation on which we agreed at the workshop, and
the reasons are mostly the same.

4.	I don't particularly care about the name for
is-character-available? (listen?), but there is an important issue
which I believe has not been raised.

	On interactive streams users may have the possibility of
erasing typed characters.  What happens if listen? returns true and
then the user erases the character?  The program which invoked listen?
will probably attempt to read a character thinking that it will not
hang but it will.  We had this bug and went to a fair amount of hair
to get it fixed.

	I see two possible solutions to this:

	- Listen? locks the character if it returns true.  This is
ugly since read-character may not be performed for a while, and may
even be bypassed (error exit, etc.)

	- Listen? is polymorphic and returns either '() or a character
object if one is available.  This assumes that the set of character
objects is disjoint from the set { '() }.  No further call to read is
needed.  Listen? would then more appropriately be called
non-blocking-read-char.  I advocate for this solution.

5.	We have not talked at all about keyboard interrupts.  It seems
to me that any reasonable implementation should provide a way for the
user to (at least) abort an infinite loop.  It would be nice if we had
a simple standard mechanism for doing this, but implementations would
be free to have more keyborad interrupts (we currently have 5 by
default).  I propose that we choose some control character (^G, for
example) which on all implementations and unless inhibited (an editor
may want to do this) will interrupt Scheme and make it return to the
top-level read-eval-print loop.