[mercury-users] exceptions considered bloody annoying

Michael Day mikeday at bigpond.net.au
Mon Apr 15 15:40:15 AEST 2002


During the debates relating to a streams design for Mercury a number of
potential interfaces were scrapped as they didn't work well with
exceptions. One of the final contenders was with_stream:

pred with_stream(filename, pred(stream, stream), io, io).
mode with_stream(in, pred(di, uo) is det, di, uo) is cc_multi.

or along those lines. It would catch any exceptions thrown by the
predicate and close files or deallocate resources before rethrowing the
exception, guaranteeing no leaks.

It's not an amazing interface, as user code has to be structured
specifically to use it and it can be awkward to manipulate multiple
streams at once in an arbitrary fashion. Also it's cc_multi, which
effectively makes everything cc_multi, and confuses people.

I have a similar interface to with_stream that looks like this:

pred with_stuff(pred(stuff, T, T), T, T, io, io).
mode with_stuff(pred(in, di, uo) is det, di, uo, di, uo) is det.

This is the only way to get at an instance of stuff, which is cached and 
can be thrown away at any time, so the code can't leave references to it 
lying around. As with with_stream, the predicate can guarantee that 
resources are managed correctly as within with_stuff it's not possible to 
do anything that would jeopardise the instance of stuff you have been 

However, what if the predicate throws an exception containing stuff? In
that case, the instance of stuff could slip out of with_stuff and do
horrible things, without the user having done anything wrong. (The same
problem applies to with_stream, but the user would have to use
unsafe_promise_unique to use the stream afterwards, and deserve whatever
they get).

So, with_stuff has to catch all exceptions and then throw a *different*
exception, along the lines of "this code threw the following exception".

And again, everything ends up cc_multi.

It just feels like C++, where exceptions are easy to throw, easy to catch,
but screw up interfaces in ways you would never expect.

Quick quiz: does anyone regularly catch exceptions other than at the very
top level of their program? How often do people find themselves using
"throw" compared to just "error"?


mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe

More information about the users mailing list