On Sun, 22 Mar 2009, nicolas.pouillard wrote:

Excerpts from Henning Thielemann's message of Sat Mar 21 22:27:08 +0100 2009:

Maybe you know of my packages lazy-io and explicit-exception which also
aim at lazy I/O and asynchronous exception handling.

I was indeed aware of these two packages but I think they hold orthogonal
ideas.

About the lazy-io package, as explained in the documentation one has to
carefully choose which operations can be lifted. In safe-lazy-io I try
to choose a set of well behaving combinators to replace 'getContents' in the
IO monad.

Moreover if I take the three problems of standard lazy IO in turn:
1/ Control of resources: One advantage over standard lazy IO is that
  the file opening can also be done lazily, avoiding an immediate
  resource exhaustion. However one still relies on evaluation and garbage
  collection to take care of closing handles, which is not satisfying since
  handles are scarce resources.
2/ Control of exceptions: If one writes a 'getContents' function such that
  it no longer hides I/O errors during reading, how do you guarantee
  that exceptions will happen during the LazyIO.run and not after?

Currently I cannot guarantee anything. However my idea is to stay away from built-in exceptions in IO. In explicit-exception there is an experimental hidden module which provides an IO monad wrapper called SIO which cannot throw any IO exception.
  http://code.haskell.org/explicit-exception/src/System/IO/Straight.hs
Actually, I think it's the wrong way round to build an exception-free monad on top of one with exceptions. Instead IO should be built on top of SIO, but that's not possible for historical reasons.
 The only safe operation to get into SIO is
  ioToExceptionalSIO :: IO a -> ExceptionalT IOException SIO a
That is, it makes exceptions explicit and SIO operations can never throw IO exceptions. You should convert synchronous explicit exceptions of atomic operations like getChar into asynchronous explicit exceptions, combine them lazily to big operations like getContents. Then you get
  getContents :: SIO (Asynchronous.Exception IOException String)
 If you run lazy SIO operations you can't become surprised by exceptions.

3/ Determinism: when freely combining multiple inputs one risks the problem
  mentioned by Oleg [1], when using your package it will depend on
  the 'getContents' function we use:
  a) if we 'liftIO' the standard 'getContents' function, we can have the issue.
  b) if we write a new 'getContents' as below [2], then (if I got right
     your lazy IO monad) all reads are chained. And then one has
     to process inputs in the same order.

I wouldn't build hClose into getContents, because you never know, whether the file is read until it's end. If you call a LazyIO.getContents twice, the contents are read sequential. In order to read file contents simultaneously you must call (LazyIO.run LazyIO.getContents) twice in the IO monad.
_______________________________________________
Haskell-Cafe mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/haskell-cafe

Reply via email to