
On Sun, Jan 28, 2007 at 05:46:06PM +0100, Peter Simons wrote:
Hi David,
Hi Peter,
I'd prefer a function of the type "timeout :: Int -> IO a -> IO a" which just throws the exception when there's an error. I like exception handling.
A timeout event can be signaled using both exceptions and a return code ('Nothing'), and there are valid arguments that favor either approach. In my humble opinion, an exception is an _exceptional_ event. It is something you didn't expect to happen. When I read from a socket, but that socket doesn't work anymore because the peer suddenly closed the connection, then that is something I want to have reported as an exception. When I read from a socket, but can't because the input stream has reached EOF, then that is _not_ an exception, that is EOF, a state every stream reaches eventually.
The difference is that there already exists a whole framework for dealing with exceptions in a pretty way, and I'd like to make use of that. Actually, reading beyond EOF does raise an exception, doesn't it? In my opinion, whenever external forces prevent my code from doing what it's trying to do, that's an exception, and my preference is to use exceptions to describe that, as they're readily handled in a modular way, without manual threading of error information. We could have readChar :: IO (Maybe Char) but we don't, because then every bit of code that uses readChar would have to deal with the exception, instead of having it propogated up to the handler written by the coder.
In terms of timeout, I prefer the "Maybe a" return type because when I say "timeout n f", a timeout event is an expected result, not an unexpected one. Besides, the computation
timeout n f >>= maybe (fail "timeout") return
is no major effort to write and has the neat advantage that it doesn't dictate the type of the exception thrown in case of a timeout. I like the fact that the dynamic exception used internally isn't visible on the outside.
Alternatively, it's also no hard work to write (Just `fmap` timeout n t) `catch` (\_ -> return Nothing) or (Just `fmap` timeout n t) `catchTimeout` (return Nothing) In the standard libraries, I prefer simplicity of exception handling. As you've written it, every library that uses timeout (e.g. an http client library, etc) would need to implement their own exception handling for timeout errors. That doesn't seem like a plus, to me. -- David Roundy http://www.darcs.net