[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Lazy catch behaviour
From: |
Neil Jerram |
Subject: |
Re: Lazy catch behaviour |
Date: |
11 May 2001 18:08:45 +0100 |
User-agent: |
Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7 |
>>>>> "Neil" == Neil Jerram <address@hidden> writes:
[ talking about lazy-catch and evaluator traps ]
Neil> 1. Is the current lazy-catch behaviour useful? Certainly
Neil> not in this case, and for most uses of the evaluator trap
Neil> handlers that I can imagine. Can anyone suggest any cases
Neil> where it is positively useful to unwind the dynamic context
Neil> before invoking the lazy catch handler? I realize that we
Neil> have to be careful about making sure that the lazy-catch is
Neil> not active during the execution of its own handler, but
Neil> couldn't we special-case that?
Neil> On the other hand, if we don't unwind the dynamic
Neil> context, a lazy catch handler call is basically just the
Neil> same as calling the handler inline instead of the throw.
Neil> Could the evaluator trap handlers be implemented as simple
Neil> procedure calls rather than by throwing exceptions?
Neil> 2. There's a readline reentrancy bug in there somewhere.
I found the source of the readline reentrancy problem, but really it
just highlights a general problem with lazy-catch, and suggests to my
mind that lazy-catch is a rather Bad Thing.
The reentrancy problem occurs because handle_error in readline.c
assumes that scm_handle_by_throw does not return. But with a lazy
catch in place, it can return. We can fix up the value of in_readline
by adding `++in_readline;' after the scm_handle_by_throw, but that
just takes us on to the next problem, which is that scm_readline
returns SCM_UNSPECIFIED, which its callers aren't expecting.
In general, lazy-catch breaks the reasonable assumption of code
everywhere that, when you do a throw, it isn't going to return. (It
reminds me of some proprietary code that I worked on, where asserts
were encouraged, but you sort of had to cope with the asserts being
compiled out as well, since some customers did that!)
AFAICT, we mainly use lazy-catch in Guile to implement stack saving
(for backtraces). I think we could achieve this in a better way by
defining a procedure-based protocol for errors. For example, we could
do something like:
- Make sure that all libguile errors and Scheme-level errors signalled
by calling `(error ...)' come through a single place, say
`error-junction'.
- Have `error-junction' call `current-error-handler'.
- Define `default-error-handler', which handles the error by throwing.
- (define current-error-handler default-error-handler).
Then we (both users and Guile central) can do stack saving and other
things by redefining current-error-handler, and we don't need
lazy-catch anymore.
What do you think?
Neil