Bill Allombert on Fri, 11 Sep 2009 18:30:56 +0200


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

Re: TRY/CATCH is unnecessarily slow on OS X


On Thu, Sep 10, 2009 at 08:32:28AM +0200, Lorenz Minder wrote:
> > err_catch only purpose is to implement the current stacked exceptions 
> > system which I find wholly inedequate and hope to replace.
> > 
> > Furthermore, TRY/CATCH is not documented currently,
> 
> While this is correct, no other error handling mechanism was documented
> either.  Yet, any nontrivial program needs to handle errors.

This is unfortunately true. I see that even the global PARI error handler
mechanism is not documented. 

> >and mostly here 
> > to implement the gp trap() function, which has its load of problem.
> 
> I see.  Are the problems in trap() related to CATCH/TRY itself?

It is rather the other way round: trap() specify a small set of events that
can be trapped (see documentation). The problem is that the events are too
generic. You cannot simply trap an event, look at it and if it is not what
you expected, rethrow it.

> > Adding a call-back 'cb_pari_err_restore' seems a better solution.
> 
> I think that would be a workable solution, too.
> 
> I looked at the current patch that you propose in the bug report (the
> number of which I forget).  There's an issue with this solution that
> makes it currently still unsatisfactory for me:  An error message is
> emitted to stdout before the handler is called.

It is not emitted to stdout. Instead it is emitted throught the
structure pariErr which is by default defaultErr (which output to stderr), but
this can be redefined in any way you want. Of course this is not documented.
Another place where PARI interface could be improved.

> I think it really should not do that, it's a library after all.  What if
> I want to use stdout to write results of my calculation to?  What if an
> error is in fact some outcome that I can handle perfectly well? (Think
> of ECM, for example.)

Actually, I have another plan: when an error happens, pari_err would
construct a GEN object containing the error data (the message, the
arguments) and sent it to the exception handler to decide its fate.

Unfortunately it is very tedious to implement.

Under GP there would be a function 
iferr(code,E,rec) (where E is a variable, code and rec are GP code
('inline closure' in the doc/develop.tex).
code is executed. If an error occurs rec is evaluated which the variable
E set to the error data. rec can call error(E) to rethrow the error.

This would remove the need of global_err_data and be usable inside GP.

> Do you think it would be possible to write the error message to a string
> instead and pass that to cb_pari_err_restore, which then can print it or
> otherwise use it?
> 
> That would be a big improvement.

That would be the job of cb_pari_handle_exception. 
cb_pari_err_recover is only meant to recover from the error, not processing
it (cb_pari_handle_exception is called in the context of the error,
cb_pari_err_recover is called after the context has been cleaned up). Maybe
they should be merged eventually though.

> > > I was actually going to propose a small change that makes it possible
> > > for users to avoid anything setjmp()/longjmp() based, provided they can
> > > come up with a viable alternative.  The idea is as follows.
> > 
> > I think it would be better to provide the user with the mean to implement
> > their own TRY/CATCH alternative, and keep the setjmp()/longjmp() one
> > for internal libpari use.
> 
> When it comes to libpari 2.3.x, is there any ill-effect if an
> application uses TRY/CATCH?  If so, what else should it use?

Outside possible compatibility problem with future versions and a rigid
interface, I do not see any problem with TRY/CATCH, and there is no alternative
currently.

Cheers,
Bill.