
Does DB.getTables use 'unsafeInterleaveIO'?
I would think that if an unsafe operation was *not* used, DB.disconnect could *not* execute before DB.getTables has returned every row.
Either way, by the Principle of Least Surprise http://en.wikipedia.org/wiki/Principle_of_least_astonishment, I think Tim's original code ought to be made to work, despite not leveraging laziness.
If you are going to tuck away an unsafeInterleaveIO, it seems reasonable that an explicit disconnect should force those deferred operations to be evaluated. Maybe the same should be done for hGetContents/hClose too? I wonder how to arrange this. An ugly solution is to explicitly keep a
Greg Fitzgerald wrote: pointer to the next unevaluated entry, advancing it in the interleaved IO operation. A leaky solution is to keep a reference to the list, and force it all. This reminds me a lot of the selector thunk optimization, where the GC notices thunks that are just a pattern match and projection from a tuple (or other single-constructor type), and does the pattern match itself if it sees that the tuple is already evaluated. It seems a similar thing is safe with some other functions, like taking last of some list. For as much as the spine has been evaluated, the GC can reduce references to the early part of the list by unfolding the function a few steps. If a deepSeq could be treated the same way (and seq is like a degenerate case of waiting till something is evaluated but not matching on it), then it would be nice and elegant to cache a thunk of (deepSeq results) in the Handle, and force it when the handle is closed. On the other hand, it's more complicated if you also want the option of telling the DB to stop sending results if you see that the list has become garbage. I suppose you could probably sort it all out by keeping a weak reference to the deepSeq, and putting a finalizer on something else. Brandon