
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