Final bikeshedding call: Fixing Control.Exception.bracket
John Lato
jwlato at gmail.com
Thu Nov 13 21:06:18 UTC 2014
On 12:31, Thu, Nov 13, 2014 Yuras Shumovich <shumovichy at gmail.com> wrote:
TLDR: the proposal is still a bad idea :))))))
IMHO it's better than the current situation.
On Thu, 2014-11-13 at 18:20 +0000, John Lato wrote:
> hClose is a good example because it's pervasive and currently incorrect.
> But it's not the only one, and furthermore a lot of broken code is likely
> in libraries.
hClose is pervasive, but it doesn't mean the bug in it affects a lot of
code. Probably 99.(9)% hClose uses are correct. (it may affect more code
then I think, but nobody even created a ticket yet!) Do you really think
it is common to close handle while using it from other thread?
No, but that's not a general requirement for this problem to manifest.
Besides, why shouldn't one be able to safely close a handle while another
thread may be using it, without using arcane functions?
But yes, there is a lot of broken code in libraries. But we should fix
bugs instead if hiding them.
This isn't about hiding bugs. It's about changing the semantics of
exception handlers so that they are more likely to match what's desired in
the general case.
>
> For the most part, Haskellers don't need to worry about async exceptions.
> using them properly is a rather rare skill currently, and I suspect people
> are basically happy with that. But it's dangerous because people actually
> do need to write async-safe code in cleanup handlers to get the behavior
> that usually mean. One reason I think changing bracket etc is a better
> solution is that it helps minimize the average programmer's exposure to
> async exceptions. It becomes easier to write correct cleanup handlers,
for
> everyone. And if someone really needs an interruptible handler that can be
> available by a specialized function. But bracket and catches aren't the
> place for that.
Haskellers don't *want* to worry about async exception, but then should.
Otherwise let remove exception from language (yes, including synchronous
-- average Haskeller doesn't worry about them too.)
Why should Haskellers worry about async exceptions? The vast majority will
never use them. They are difficult to reason about and difficult to use
properly, and it's only because certain aspects of the RTS (and killThread)
are implemented with them that most people ever encounter them.
The proposal makes it easer to continue ignoring async exceptions. That
is why I'm arguing here against it. (Possible breakage if existing code
worries me too, but much less)
I think it's a good thing to make it easier to ignore async exceptions.
It is common myth that bracket saves you from async exceptions, but that
is simply not true. And the proposal will not make it true. So newcomers
learn to ignore async exceptions and continue doing that forever.
Even worse, when newcomer finally find out (most likely itself!!!), that
the myth is wrong, he doesn't get help from the community -- no docs, no
tutorials, no blogs. Everything he can find is a set of myths.
Or we could make the implementation match the common knowledge. Then it
wouldn't be a myth, it would be true.
I started learning haskell 8 years ago, and I'm paid for haskell code 3
years already. When do you think I discovered that bracket is not enough
to handle async exceptions? Half a year ago(!)
I'll post the link again:
http://haskell.1045720.n5.nabble.com/Control-Exception-bracket-is-broken-td5752251.html
Note that nobody answered the question about hClose. Nobody explained
how to use interruptible exceptions in cleanup. Very few people actually
even care to replay. Because everybody learned to ignore async
exceptions.
Did you read this: http://www.well-typed.com/blog/97/
?
I hope you did. Because it is probably the *only* deep discussion of
*some* of the related issues. Unfortunately it appears after too late
for me, so I spent a lot of days discovering everything myself.
Wouldn't it be better if stuff like that just worked out of the box?
People could still spend days learning it, but they wouldn't be bitten by
these hard-to-identify, poorly-understood bugs.
I even wrote my own library for exception handling:
https://github.com/Yuras/io-region/
I'm still not sure it is good. It even can be buggy. But I considered a
lot of design decisions, including unintrruptibleMask, and found then
unsatisfactory
.
I personally find it easer to write exception safe code with io-region,
but you should understand async exceptions anyway. There is no easy way
unfortunately.
That doesn't mean we should make it harder to do the right thing.
John
>
> > > > So sync exceptions in hClose mean the program is incorrect, and the
> only
> > > > recourse is to prevent the sync exceptions in the first place.
> > > Fortunately,
> > > > these FDs are likely guaranteed to be valid so sync exceptions are
> > > > virtually ruled out.
> > > >
> > > > This is a general pattern with cleanups: a cleanup already has the
> > > > allocated resource at hand, which almost always rules out sync
> > > exceptions.
> > > > Also, exceptions during an error-induced cleanup cause dangerous
> > > > error-silencing anyway since we cannot handle an exception within an
> > > > exception.
> > >
> > > So you have to inspect all the code, directly or indirectly used by
> > > cleanup action, to ensure it doesn't throw sync exception (just to
find
> > > that it is not the case -- a lot of cleanup actions can throw sync
> > > exceptions in some, probably rare, cases.) Someone argued, that was
> > > exactly the issue the proposal was trying to solve.
> > >
> >
> > Sync exceptions have nothing to do with the proposal. The proposal
itself
> > certainly doesn't argue this.
>
> Sorry, I was not clear enough. I'm referring to the next:
>
> On Tue, 2014-11-11 at 12:17 -0800, Merijn Verstraaten wrote:
> > Both Eyal and me have had trouble with this where we had to entire
> > half of base and part of the runtime, to figure out whether our code
> > was async exception safe. Auditing half the ecosystem to be able to
> > write a safe cleanup handler is *NOT* a viable option.
>
> By banning sync exceptions in cleanup action you require Merijn to audit
> half the ecosystem to figure out whether his code is *sync* exception
> safe. Which probably requires the same amount of work as inspecting code
> for *async* exception safety.
>
> What? Nobody wants to ban sync exceptions in cleanups. They should
> continue to work the way they do now. Why do you bring this up?
I'm referring to this:
> > > > > So sync exceptions in hClose mean the program is incorrect, and
the
> > only
> > > > > recourse is to prevent the sync exceptions in the first place.
What can it means except banning sync exceptions?
Actually I seriously considered baning exceptions in cleanup action,
but found it unsatisfactory
Sorry for long email.
Thanks,
Yuras
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20141113/41aa2817/attachment.html>
More information about the Libraries
mailing list