Lazy IO is useful! [Was: "interact" behaves oddly...]

Simon Marlow simonmar at
Thu Oct 2 11:25:59 EDT 2003

> main =
>   do let mylist = [1..10000]
>      writeFile "myfile.txt" (unlines (map show mylist))

This part does run in O(1) space and isn't problematic.

> --   ...
>      mylist' <- (map read . lines) `fmap` readFile "myfile.txt"
>      let result = sum mylist'
>      print result

Indeed, this works by interleaving the I/O and the computation of the
result.  It is a convenient way to program, because you can use ordinary
list operations on the I/O stream.  We know it is not "safe": a
programmer can observe the fact that implicit I/O is going on.

It is also not a good way to program:  you have no way to catch errors
and take appropriate action if the implicit I/O should fail in some way.
Should we really be encouraging the writing of programs that have no
error checking?

> With lazy IO, this program too should run in constant space, and the 
> functions that consume the large intermediate structure can remain 
> unchanged!
> So, I think a lazy programming language should support not only lazy 
> evaluation, but also lazy IO! When it is appropriate to abstract away 
> from the details of when IO happens, lazy IO is useful. It can 
> facilitate separation of concerns and modularity, just like lazy 
> evaluation. Appropriate lazy IO should not compromise the 
> purity of the language or be an obstacle to optimistic evaluation. 

I look forward to seeing a form of lazy I/O that doesn't suffer from
these problems!  (although I suspect I still won't use it :-p)


More information about the Haskell-Cafe mailing list