[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Finally clauses




On Thu, 29 Aug 2002, Michael Sperber [Mr.  Preprocessor] wrote:

>
>Bear> They could capture continuations or call captured continuations
>Bear> the same as any other procedure.  No critical resources or
>Bear> global variables are implied or required, nothing that creates
>Bear> a race condition in multiprocessing is entangled, and the
>Bear> semantics becomes clean and provable again.
>
>What precisely are the semantic issues with SRFI 34 you're worried
>about?  I sure don't see any that would create race conditions or
>interact unpleasantly with multiprocessing.

I am concerned that the "current exception handler" seems to be
global -- a property of the program rather than an individual
thread.

In a situation where I want to have different threads doing
different things, it makes sense to have different exception
handlers for them.  For example, I may have one thread that's
trying to compute a regression average; if it attempts to
divide by zero because there are no data, I want its exception
handler to return zero as a result.  At the same time, a
different thread is attempting to open a file read-write and
seek to its end preparatory to writing our regression average
into a log. If the second thread throws an exception due to
file-not-found I want its exception handler to create a file
and open it for writing. And if that (the first exception
handler) itself throws another exception then I want to call
another exception handler that signals application-halt to
all the other threads and complains about "unable to open a
file" to the user.

My reading of SRFI 34 is that the *PROGRAM* has a current
exception handler;  This is fine, I suppose, if you intend any
exception to mean halt and report the exception.  But if I want
to recover in some intelligent way from exceptions, then each
*thread* has to have its own current exception handler, because
each thread has a different "and if that doesn't work then try
this" action to do.  And also exception handlers will have to
have a clean way to be defined so that they can themselves
result in calling other exception handlers.

In my use of exceptions, the thread that causes the exception has
little to contribute to its recovery; the exception handler needs
to be set on a per-routine basis, as an alternate method of doing
the job that routine was intended to do.  So, my programming model
would be something like this: routine A calls B with the exception
handler Bprime, then B calls C and C calls D and D runs into an
exception.  At this point, the stack frames for B, C, and D are
thrown away, an exception code is written into a reserved space in
A's call frame, and a call is made to Bprime, with the same
arguments and continuation as the original call to B.  Bprime
returns to A and processing continues normally. A never has to know
whether the procedure that returned to its post-B continuation was
B or Bprime.

If Bprime cares what caused the exception that B ran into, there's
a function for reading the exception code from the parent frame
that it can use to access that information.  But I don't usually
find it useful for the exception handler to have to care which
exception the errant call ran into; I'd prefer to throw away all
the information from the errant call-frame and treat the rest of
the computation as though the handler had been called *instead*.

The business of passing around thunks and continuations as objects
as in SRFI 34 seems to me to get in my way and complicate things,
and I don't think it actually provides more generality or
functionality.