[Haskell-cafe] Re: Strictness, order of IO operations: NewCGI & HDBC

Brandon Moore brandonm at yahoo-inc.com
Fri Oct 20 15:33:50 EDT 2006


Greg Fitzgerald wrote:
> 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 
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


More information about the Haskell-Cafe mailing list