
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