Tue, 17 Sep 2002 05:41:40 +0100
Sigbjorn Finne wrote:
> > > Look at this small programm:
> > >
> > > module Main(main) where
> > >
> > > main = echoTwice
> > >
> > > echo = getChar >>= putChar
> > >
> > > echoTwice = echo >> echo
> > >
> > > while executing: the program reads first two chararcters and then it writes
> > > the characters, but
> > > in my opinion it would be right to read one character, then write one
> > > characater, then read, then write.
> > > What's the reason for it?
> > Buffering.
> A deficiency of the current implementation of the IO system, I'd
> say. Reading from stdin ought to force a stdout (and stderr) buffer
> flush. The GHC IO libs used to do this.
The equivalent ANSI C I/O functions typically flush either all
buffered output streams or all line-buffered output streams whenever a
read operation is passed to the underlying system call (but not when
it can be satisified from the input stream's buffer).
However, that won't make any noticeable difference unless the user
explicitly puts the input stream into unbuffered mode. If the input
stream is buffered, getChar doesn't (and shouldn't) return anything
until Return (Enter, NewLine, ...) is pressed.
> This is constant source of confusion for users & turning off
> buffering alltogether is a poor substitute for having the IO
> system do the Right Thing under the hood.
The "right" thing is a subjective notion. GHC already has some "magic"
behaviour in this regard; i.e. using:
hSetBuffering stdin NoBuffering
automatically changes the terminal settings (e.g. clearing the ICANON
flag) if stdin is associated with a terminal.
Even then, this won't "do the right thing" if the terminal itself (as
opposed to the driver) is line-buffered; nothing will.
A user who wants unbuffered input will probably argue that "the right
thing" is to make stdin unbuffered by default (along with clearing the
ICANON flag). OTOH, a user who wants line-buffered input (i.e. the
ability to use BackSpace/Ctrl-W/Ctrl-U) will probably disagree.
Glynn Clements <email@example.com>