
I'm writing a program that calculates the maximum height of a stomp rocket (or any free falling object) given the starting height of the object and the amount of time that it takes to hit the ground. Here's what I have written: http://pastebin.com/KBJdPEJd The behavior that I am expecting is something like this: Starting height (ft): [user enters something here] Total air time (seconds): [user enters something here] Maximum height (ft): [the program's answer] Another? (Y/N) Then everything starts over if the user presses y, and execution stops if the user presses n. What actually happens: 1. The program waits for user input for both of the two fields before anything else, then it prints the prompts along with the answer. 2. The user needs to press enter before the their response to "Another? (Y/N)" is reacted to. I'd rather that the response is instant after just the y or n key is pressed. I don't really understand exactly how lazy evaluation works in the context of IO, so any help will be much appreciated.

On Friday 28 October 2011, 01:20:48, Avery Robinson wrote:
I'm writing a program that calculates the maximum height of a stomp rocket (or any free falling object) given the starting height of the object and the amount of time that it takes to hit the ground. Here's what I have written: http://pastebin.com/KBJdPEJd
The behavior that I am expecting is something like this:
Starting height (ft): [user enters something here] Total air time (seconds): [user enters something here] Maximum height (ft): [the program's answer] Another? (Y/N)
Then everything starts over if the user presses y, and execution stops if the user presses n.
What actually happens: 1. The program waits for user input for both of the two fields before anything else, then it prints the prompts along with the answer. 2. The user needs to press enter before the their response to "Another? (Y/N)" is reacted to. I'd rather that the response is instant after just the y or n key is pressed.
I don't really understand exactly how lazy evaluation works in the context of IO, so any help will be much appreciated.
That's not a problem with lazy evaluation and IO, it's a simple buffering issue. While in ghci stdin and stdout are normally unbuffered, for compiled programmes, they are usually line-buffered, so nothing will actually be printed to the terminal until a newline enters the output buffer or the output buffer is full. To get the prompts output before the user enters the inputs, you need to import System.IO and then you have the choice whether you want to a) turn off buffering completely (for the programme), that means performing hSetBuffering stdout NoBuffering at the beginning of main b) manually flush the output buffer for the prompts, that means do ... putStr "Starting height (ft): " hFlush stdout rawStartingHeight <- getLine ... etc. For small programmes like this, turning off buffering is simpler, but in programmes that produce a lot of output, it adds relevant overhead to output, so then manually flushing at the desired places is preferable. For the input, the situation is similar, you can globally turn off input buffering via 'hSetBuffering stdin NoBuffering' or do it locally in yOrN. However, the above may not work on Windows (buffering control used to be broken on Windows, I don't know the current state).
participants (2)
-
Avery Robinson
-
Daniel Fischer