flushing trace debug output before getting other output

I'm working on exercise 6.16 in Thompson's "Haskell; the Craft of Functional Programming" My goal for the moment is to call printPicture to see my results: type Picture = [[Char]] printPicture :: Picture -> IO () printPicture = putStr . concat . map (++"\n") And everything is encouraging. The return type of my function syncs up: *Main> :t superimposeImage imgA imgB superimposeImage imgA imgB :: [[Char]] Now, the only issue is that I have put a number of trace statements in my program whose output is *interspersed* with the return data. The return data is simply lists of characters, where each character is "." or "#" *Main> printPicture $ superimposeImage imgA imgB siPointLogic i1 i2 0 15 .siPointLogic i1 i2 1 15 .siPointLogic i1 i2 2 15 .siPointLogic i1 i2 3 15 .siPointLogic i1 i2 4 15 .siPointLogic i1 i2 5 15 .siPointLogic i1 i2 6 15 .siPointLogic i1 i2 7 15 .siPointLogic i1 i2 8 15 .siPointLogic i1 i2 9 15 .siPointLogic i1 i2 10 15 .siPointLogic i1 i2 11 15 When I remove my various trace statements, I get what I want: *Main> printPicture $ superimposeImage imgA imgB ................ ................ ................ ................ ...........##... So the question is, how can I leave the trace statements in the code and yet get the printPicture output after all the debugging output has output? It only makes sense for it to work that way. The trace output occurs during the program and in particular, during the program *prior* to the call to printPicture. Therefore all of the trace output should have finished *prior* to printPicture outputting it's rows. -- Carter's Compass: I know I'm on the right track when, by deleting something, I'm adding functionality.

On Sun, 2005-07-17 at 04:46 +0000, Terrence Brannon wrote:
When I remove my various trace statements, I get what I want:
*Main> printPicture $ superimposeImage imgA imgB ................ ................ ................ ................ ...........##...
So the question is, how can I leave the trace statements in the code and yet get the printPicture output after all the debugging output has output?
Basically you can't. You really shouldn't rely on when the trace output will happen. The trace 'function' is basically a cheat and you shouldn't rely on it for anything other than debugging (and even then, it's not the best debugging aid).
It only makes sense for it to work that way.
Time to think again I'm afraid! :-)
The trace output occurs during the program and in particular, during the program *prior* to the call to printPicture. Therefore all of the trace output should have finished *prior* to printPicture outputting it's rows.
Because of lazy evaluation the output gets interleaved with the computation and the trace output happens during the computation so the output from both get interleaved. Think of it like this: at each step it's doing just enough evaluation to figure out the next character to print, then printing it and then going on to the next step. It is that "just enough evaluation" bit that is triggering the trace 'function' to be called and the output to actually happen. The trace 'function' exposes this (possibly confusing) lazy evaluation order which most of the time you can be blissfully unaware of. It is for just this reason (that it'd be horribly confusing) that Haskell does not allow side effects in functions. And what does trace do? It has side effects (the console output). This is why I said trace is a 'cheat'. It is not an ordinary Haskell function and cannot be defined using ordinary Haskell. Avoid it if you can. A pragmatic answer to your question is just to note that the trace output goes to stderr while the ordinary output goes to stdout so you can redirect the stderr to a seperate file and thereby not see the interleaving. ./prog 2> stderr.log cat stderr.log Duncan
participants (2)
-
Duncan Coutts
-
Terrence Brannon