Front page | perl.perl5.porters |
Postings from April 2010
Re: Try::Tiny in Core?
Thread Previous
|
Thread Next
From:
Zefram
Date:
April 10, 2010 14:06
Subject:
Re: Try::Tiny in Core?
Message ID:
20100410210605.GA17280@lake.fysh.org
Yuval Kogman wrote:
>1. some way to be sure that the error that was thrown does not get
>lost due to stack unwind operations
This is top of my list, too, for desired core changes. My favourite
failure mode right now is that "local $@" (between eval{} and die), by
restoring an old value of $@, will clobber an exception being thrown.
Nasty when "local $@" is also the way to avoid clobbering in some cases.
I think all that's required to fix this is that Perl_die_where()
stores the exception in a local C variable, rather than in ERRSV,
while unwinding the Perl stacks. The exception should go into ERRSV
last thing before longjmping, alongside setting PL_restartop. Some of
the protocol in immediate callers could (non-essentially) also change,
to avoid putting exceptions into ERRSV earlier. I'm intending to submit
a patch once blead is open for features once again.
>2. reliable signaling of failure. my $failed = not eval { ...; 1 } is
>very ugly,
Fixing the first one fixes this. When $@ is no longer clobbered,
testing $@ immediately after eval{} will reliably test for failure.
(Unless, perhaps, you were talking about $@ being clobbered by signal
handlers. I think we should tackle that by implicitly saving $@ et al
across calls to signal handlers.)
>3. a better mechanism than $SIG{__DIE__}
Its current semantics are a pain, but can't really be changed, because
everyone relies on them.
In the Common Lisp system there are a couple of hooks, *debugger-hook*
and *break-on-signals*, which do essentially the job of $SIG{__DIE__},
but they take effect in much more specific ways than $SIG{__DIE__} does.
(See <http://www.lispworks.com/documentation/HyperSpec/Body/09_.htm>
if you're insanely curious.) I'll be replicating these features in
my Lisp-like condition system, independent of $SIG{__DIE__}, but of
course those hooks natively only apply to conditions signalled within
the Lisp-like system.
$SIG{__DIE__} does, however, have a substantial role in relation to the
Lisp-like system. It's very useful as a way to bring non-Lisp exceptions
into the Lisp system. Where code uses the Lisp system, it can locally set
this hook, and then use the Lisp mechanisms to handle exceptions generated
by code that it calls that doesn't use the Lisp system. The same would
potentially apply for any other complete exception system. So, despite
the pain it's caused, $SIG{__DIE__} can do us one last great favour.
>Some code defensively sets $SIG{__DIE__} to ''
Yes. One has to do this, if one is relying on being able to catch a
specific expected exception in the expected way. I think we ought to
have some syntactic sugar for "eval { local $SIG{__DIE__}; ... }",
if people are going to go on using such thin layers over eval/die.
But it's not pressing.
>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.
That's the sort of thing I'm aiming at. I think we shouldn't be coring
any specific exception system at the moment (and possibly not ever). We
should be trying out exception systems on CPAN, and see what people like.
The core should be made more amenable to writing this sort of extension.
The core changes needed here are more about scoping behaviour than about
exceptions per se. (I have a short wishlist resulting from writing
Scope::Escape, which I'll elaborate on when blead is open for business.
See the gripes in the S:E documentation if curious.)
-zefram
Thread Previous
|
Thread Next