
Hello all. I'm new to functional programming and Haskell, but have been programming in C and Java for a while. I've been going through the tutorials and whatnot on haskell.org. I've read from the Gentle Introduction to Haskell about IO and some of the other stuff and I have a question about it. main = do putStr "Type Something: " str <- getLine putStrLn ("You typed: " ++ str) When compile and run this code the "Type Something: " isn't displayed until the putStrLn. So there is no prompt. The output looks like this. s Type Something: You typed: s But if I change the putStr "Type Something: " to a putStrLn or put a \n at the end of the string it displays the text immediately (ie, when I want it to). Is there a good reason for this? Am I doing something wrong? Or do I need to call some kind of standard output flush? Thanks. Oh, I'm using ghc. Matt -- "Not everone knows Josiah Royce's definition of a liar as a man who willfully misplaces his ontological predicates, but everyone who has ever told a lie will recognize its accuracy." Ch. 94: Truth - "The Great Ideas: A Synopticon of Great Books of the Western World"

On Fri, 12 Sep 2003 16:27:59 -0600
Matt O'Connor
Hello all. I'm new to functional programming and Haskell, but have been programming in C and Java for a while. I've been going through the tutorials and whatnot on haskell.org. I've read from the Gentle Introduction to Haskell about IO and some of the other stuff and I have a question about it.
main = do putStr "Type Something: " str <- getLine putStrLn ("You typed: " ++ str)
When compile and run this code the "Type Something: " isn't displayed until the putStrLn. So there is no prompt. The output looks like this.
s Type Something: You typed: s
But if I change the putStr "Type Something: " to a putStrLn or put a \n at the end of the string it displays the text immediately (ie, when I want it to). Is there a good reason for this? Am I doing something wrong? Or do I need to call some kind of standard output flush?
Yes, the problem is that the first line is not being flushed. Importing hFlush and stdout from IO (or System.IO) and adding hFlush stdout after you putStr will fix it. Alternatively, you could change the buffering on stdout to NoBuffering. I don't know if there is a standard putStrWithFlush function or just a better answer than this. A putStrWithFlush would be trivial to write or more generally to a HOF that flushed after performing the action passed to it.

This is a buffering problem. Use hSetBuffering to fix this (see Chapter 3 in YAHT -- www.isi.edu/~hdaume/htut/). Alternatively, use:
main = do putStrLn "Type Something:" ...
in which case the "Ln" part will force it to be printed. - Hal On Fri, 12 Sep 2003, Matt O'Connor wrote:
Hello all. I'm new to functional programming and Haskell, but have been programming in C and Java for a while. I've been going through the tutorials and whatnot on haskell.org. I've read from the Gentle Introduction to Haskell about IO and some of the other stuff and I have a question about it.
main = do putStr "Type Something: " str <- getLine putStrLn ("You typed: " ++ str)
When compile and run this code the "Type Something: " isn't displayed until the putStrLn. So there is no prompt. The output looks like this.
s Type Something: You typed: s
But if I change the putStr "Type Something: " to a putStrLn or put a \n at the end of the string it displays the text immediately (ie, when I want it to). Is there a good reason for this? Am I doing something wrong? Or do I need to call some kind of standard output flush? Thanks.
Oh, I'm using ghc.
Matt
-- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume

Hal was pretty terse, so I'll explain why switching to putStrLn will help.
stdout is line buffered.
At least by default (see hSetBuffering). That means output will only be
flushed to the screen once a newline is written. Your prompt wasn't
printed because it didn't have a newline, so it was buffered until the
second print provided one (read from the user, by way of s).
This is hardly specific to Haskell. Try this C program:
#import
This is a buffering problem. Use hSetBuffering to fix this (see Chapter 3 in YAHT -- www.isi.edu/~hdaume/htut/). Alternatively, use:
main = do putStrLn "Type Something:" ...
in which case the "Ln" part will force it to be printed.
- Hal
On Fri, 12 Sep 2003, Matt O'Connor wrote:
Hello all. I'm new to functional programming and Haskell, but have been programming in C and Java for a while. I've been going through the tutorials and whatnot on haskell.org. I've read from the Gentle Introduction to Haskell about IO and some of the other stuff and I have a question about it.
main = do putStr "Type Something: " str <- getLine putStrLn ("You typed: " ++ str)
When compile and run this code the "Type Something: " isn't displayed until the putStrLn. So there is no prompt. The output looks like this.
s Type Something: You typed: s
But if I change the putStr "Type Something: " to a putStrLn or put a \n at the end of the string it displays the text immediately (ie, when I want it to). Is there a good reason for this? Am I doing something wrong? Or do I need to call some kind of standard output flush? Thanks.
Oh, I'm using ghc.
Matt
-- Hal Daume III | hdaume@isi.edu "Arrest this man, he talks in maths." | www.isi.edu/~hdaume
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Brandon Michael Moore wrote:
Hal was pretty terse, so I'll explain why switching to putStrLn will help.
stdout is line buffered.
At least by default (see hSetBuffering). That means output will only be flushed to the screen once a newline is written. Your prompt wasn't printed because it didn't have a newline, so it was buffered until the second print provided one (read from the user, by way of s).
This is hardly specific to Haskell. Try this C program:
But there's one significant difference between C and Haskell, which is
applicable in the case of Matt's program. In C, any line-buffered
output streams are automatically flushed when a read from an
unbuffered or line-buffered stream can't be satisfied from its buffer.
Also, it seemed fairly clear from Matt's original message that:
a) he didn't want to have to force a new-line (he noted that doing so
eliminated the problem), and
b) he understood the concept of flushing, but presumably didn't know
how to do it in Haskell.
While we're on the subject, I'll point out a couple of other
differences between the buffering in ANSI C's stdio library and
Haskell's:
1. In Haskell, you can change the buffering mode at any point; in C,
you have to change it before any data is read from or written to the
stream, otherwise the behaviour is undefined.
2. For an input stream which is associated with a tty, changing the
buffering mode may also change the terminal settings (setting it to
unbuffered disables canonical mode while setting it to line-buffered
or fully-buffered enables it).
--
Glynn Clements

On Sun, 14 Sep 2003, Glynn Clements wrote:
Brandon Michael Moore wrote:
Hal was pretty terse, so I'll explain why switching to putStrLn will help.
stdout is line buffered.
At least by default (see hSetBuffering). That means output will only be flushed to the screen once a newline is written. Your prompt wasn't printed because it didn't have a newline, so it was buffered until the second print provided one (read from the user, by way of s).
This is hardly specific to Haskell. Try this C program:
But there's one significant difference between C and Haskell, which is applicable in the case of Matt's program. In C, any line-buffered output streams are automatically flushed when a read from an unbuffered or line-buffered stream can't be satisfied from its buffer.
Interesting. I didn't know this. Maybe we should match this behaviour, or provide a write-string-and-flush function. It seems like this issue is causing an undue amound of trouble.
Also, it seemed fairly clear from Matt's original message that:
a) he didn't want to have to force a new-line (he noted that doing so eliminated the problem), and
I should note here that there is a gnu readline binding distributed with GHC. It's undocumented, but it seems to follow the C API pretty closely, and you can make a decent interface using only two of the functions.
b) he understood the concept of flushing, but presumably didn't know how to do it in Haskell.
While we're on the subject, I'll point out a couple of other differences between the buffering in ANSI C's stdio library and Haskell's:
1. In Haskell, you can change the buffering mode at any point; in C, you have to change it before any data is read from or written to the stream, otherwise the behaviour is undefined.
2. For an input stream which is associated with a tty, changing the buffering mode may also change the terminal settings (setting it to unbuffered disables canonical mode while setting it to line-buffered or fully-buffered enables it).
-- Glynn Clements
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Matt O'Connor wrote:
Hello all. I'm new to functional programming and Haskell, but have been programming in C and Java for a while. I've been going through the tutorials and whatnot on haskell.org. I've read from the Gentle Introduction to Haskell about IO and some of the other stuff and I have a question about it.
main = do putStr "Type Something: " str <- getLine putStrLn ("You typed: " ++ str)
When compile and run this code the "Type Something: " isn't displayed until the putStrLn. So there is no prompt. The output looks like this.
s Type Something: You typed: s
But if I change the putStr "Type Something: " to a putStrLn or put a \n at the end of the string it displays the text immediately (ie, when I want it to). Is there a good reason for this? Am I doing something wrong? Or do I need to call some kind of standard output flush? Thanks.
Yes; if you don't want a newline after the prompt, you need to use:
hFlush stdout
to flush the stream.
--
Glynn Clements
participants (5)
-
Brandon Michael Moore
-
Derek Elkins
-
Glynn Clements
-
Hal Daume III
-
Matt O'Connor