develooper Front page | perl.perl5.porters | Postings from April 2010

Re: Try::Tiny in Core?

Thread Previous | Thread Next
From:
Yuval Kogman
Date:
April 10, 2010 13:20
Subject:
Re: Try::Tiny in Core?
Message ID:
i2wa891e1bd1004101319n554b0a71o79dd40f98d8cf2be@mail.gmail.com
As the author of Try::Tiny i'd just like to chime in with the general
atmosphere.

IMHO it is a bandaid, not a solution. It would be unhappy if it was cored.

I would personally like to see a much more comprehensive error
catching facility that does not involve $@.

As Zefram said, something like lisp conditions seems to be the most useful.

However, I also think it's premature to add something feature that's
supposed to be feature complete. As I see it the mess has to be
cleaned up first.

My personal wishlist for an initial core feature would have:

1. some way to be sure that the error that was thrown does not get
lost due to stack unwind operations that happen between the try and
the die (additional eval { } and die in DESTROY, both of which can
alter $@)
2. reliable signaling of failure. my $failed = not eval { ...; 1 } is
very ugly, propagating context is a PITA, etc. this could be done with
an additional variable, but that is just something else that needs to
be localized, and doesn't solve the context propagation problem
because you still need to run things after the eval block.

The most likely way I see this happening is by extending the eval op
to also allocate a dynamically scoped container (that lives on the
context stack) into which 'die' will accumulate errors (in addition to
the assignment to errsv, and the reason the stack was unwound is also
recorded.

It doesn't have to be pretty, just simple, predictable and reliable,
while retaining compatibility with existing code.

If we have those two, at the very least make Try::Tiny feature
complete (errors will no longer be lost due to misbehaving
destructors), and possibly simplifies the code.

And then there's another issue, which Try::Tiny isn't affected by, but
which is important too IMHO:

3. a better mechanism than $SIG{__DIE__}

There are numerous cases in which $SIG{__DIE__} is used/abused:

- Carp::Always changes the default formatting of errors
- Carp::REPL lets the user inspect the error before it is thrown
(usage as a hook, in this case a debugging aid)
- several large apps use it to record errors for more informative
reporting, logging, etc (usage as an event handler, with no effect on
the handling)

and of course there are other uses.

Some code defensively sets $SIG{__DIE__} to '' because of this wide
range of uses, that occasionally interferes when you need "normal"
exceptions (an oxymoron if i ever saw one, but whatever). In fact,
people have repeatedly requested that Try::Tiny do this as well, but
I'm opposed since this will cause try { } and eval { } to behave
differently in more than just the lexical scope where the eval { } was
replaced by the try { }, but also inside the erroring code.

I don't know what the solution to this problem is at the core level,
but intuitively I would say that a condition like system should layer
on top of a reliable but simple infrastructure.


What i'm concerned about is that there is a tendency to add gratuitous
features to error handlers so that they would be more reliable and
informative when collecting errors, and more concise when handling
them to encourage that they are handled properly. They must also
accommodate a wide variety of styles and preferences.

Because of this I feel very strongly that the syntactic layer for a
try/catch mechanism should be developed by experimentation, allowing
different styles to compete, like they do today.

The reason CPAN solutions are not really available today is that
writing a quality error handling module is very difficult (tons of
cargo culting is required) and performance is always disappointing.

Devel::Declare theoretically solves the performance limitations on
some level. A better hook mechanism than $SIG{__DIE__} will help with
the other end of that equation, and a foundation that's more reliable
and cleaner than eval/die/$@ would make it much easier to focus on the
syntactic challenge instead of the engineering problems. There are
clever and aesthetically pleasing error handling modules on the CPAN
right now that I wouldn't touch with a 10' pole because I've read
their internals.

If this does work then we can know what a real candidate for taking
the coveted 'try' keyword should look like, preferably one that is
tailored for the code that is really out there (new code, old code,
and perhaps most importantly applications which mix the old and the
new code so that migration isn't too hard).

Anyway, my ¢2

Cheers,
Yuval

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About