Lazy streams and unsafeInterleaveIO

Wed, 25 Dec 2002 16:34:21 -0800

Glynn Clements wrote:

>Jyrinx wrote:
>>>[...] and
>>>the inability to handle exceptions (the actual exception won't occur
>>>until after e.g. getContents has returned).
>>But how does this differ from strict I/O? I mean, say there's a disk 
>>error in the middle of some big file I want to crunch. Under traditional 
>>I/O, I open the file and proceed to read each piece of data, process it, 
>>and continue to the next one, reading the raw data only as I need it. 
>>When I hit the error, an exception will be thrown in the middle of the 
>>operation. In lazy I/O, I might use getContents to get all the 
>>characters lazily; the getContents call will read each piece of data as 
>>it's needed in the operation - in other words, the data is read as the 
>>program uses it, just like with traditional I/O. And when the error 
>>occurs, the operation will be unceremoniously interrupted, again the 
>>same as by strict I/O. In mean, if an exception is thrown because of a 
>>file error, I can't hope to catch it in the data-crunching part of the 
>>program anyway ...
>No, but with strict I/O, you are bound to be "within" the IO monad
>when the exception is thrown, so you *can* catch it.
>If you are just going to allow all exceptions to be fatal, and don't
>need any control over I/O ordering, you may as well just use lazy I/O. 
>However, if you are writing real software as opposed to just toy
>programs, you have to handle exceptions; e.g. a web browser which died
>every time that a server refused a connection wouldn't be of much use.
Sure - and that's why I don't do *everything* in purely-functional-land. 
I suppose what I'm going for is separation of concerns: Anything with 
any business catching exceptions should be in the IO monad; 
calculations, transformations, etc., which depend on such a continuous 
stream of data couldn't deal with the exception if I wanted them to, but 
the IO code that invokes them can. In the Web browser example, I imagine 
(and this is off the top of my head) that a major functional part of the 
program would be a function that takes a bunch of HTML (presumably 
passed as a lazy stream from a server, achieved in the IO monad), 
processes it, and renders a bunch of graphical data for the screen (of 
which IO code could control the display). If a connection is refused, IO 
code catches the error before it can pass the stream to the rendering 
function; if a connection is cut off or something, the rendering code 
can't deal with that, and the exception gets caught back in I/O-land.

Luke Maurer