Karim BELABAS on Thu, 12 Sep 2002 20:50:15 +0200 (MEST)


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

Re: error recovery (was Re: gp: series bug)


On Wed, 11 Sep 2002, Ilya Zakharevich wrote:
> On Thu, Sep 12, 2002 at 12:36:03AM +0200, Karim BELABAS wrote:
> > > >   CATCH(numerr) {
> > >
> > > I do not think the situation with one trap to catch is frequent enough
> > > to make this interface useful.
> >
> > Please elaborate. I'm note sure I understand your point. You'd rather have a
> > general CATCH(CATCH_ALL), and no specific error number ?
>
> > Well, if I only want to catch "precision error in truncation", I'd rather have
> >
> >   CATCH(precer) { ...; }
> >
> > than
> >
> >   CATCH(CATCH_ALL) {
> >     CATCH_RELEASE();
> >     switch (pari_errno) {
> >       case precer: ...; break;
> >       default: THROW(pari_errno);
> >     }
> >   }
>
> Yes, I think the second interface is much better (with minor changes...).

So in fact, you'd completely remove the CATCH_ALL / numer parameter ?

Hum. Any other opinion ?

I've always wondered whether it is overkill to trap individual error types.
Under GP, probably: using a global 'errno' (say a 'default') would simplify
trap() semantics: 2 arguments only, and we wouldn't need to teach parierr.h
to trap().

[ side note: it would be much better to have defaultget(dft), rather than
the current horrible default(dft, , 1) ]

But I kind of like it in library programming.

> Too many things hidden under the hood with the first interface.

Not that many.

After CATCH(numerr), the code currently executed when 'numer' is actually
thrown, is more or less equivalent to a sequence of

  CATCH_RELEASE();
  if (pari_errno != numer) THROW(pari_errno)

until we get caught somewhere, or all catchers have been poped out.
Except it's executed as:

  /* discard specific handlers until one fits or we find a generic handler */
  while (handler->numer != numer
      && handler->numer != any_err) pop(handler);
  if (handler) longjmp(handler->env);

I don't think it's less clean (and it's certainly faster). Contrast

  Examine all handlers in the exception stack until one fits, then activate it

with

  Jump to all handlers in turn until one of them reacts

>     EXECUTE_CATCHING {
>       some code
>     } END_EXECUTE_CATCHING
>
>     if (pari_errno != precer)
>         THROW(pari_errno);
> > and have to propagate everything I get and don't like. I don't see any point
> > in complicating the interface, granted that both forms are available at
> > essentially no extra cost.
>
> IMO, your interface is more complicated.  Complication is not in the
> number of keystrokes, but in the distance between the "visual
> representation" and the flow direction and the intent of the programmer.

Traditionnal visual representation for catch/throw mechanisms is something
like

  Try {
    /* code */
  }

  Catch (err) {
    /* recovery */
  }

where mine is exactly the other way round (that's bad, OK). Do you like

  Try (err) {
    /* code */
  }

  Catch {
    /* recovery */
  }

better ?  [ assuming I keep the 'err' parameter, I have to know it before
executing 'code' ]

It could be split in two variants

    Try { code } Catch { }

which is perfectly standard

    TryNo(err) { code } Catch { }

which would emphasize the kind of error we expect in 'code', while keeping
the same visual shape.

> > It already occurs naturally 6 times in the library (+ 1 to define trap()).
>
> trap() does not count - the semantic is too ugly.

What would you propose ? I have changed slightly the behaviour of trap()
under GP in 2.2.4 [ it shouldn't change a thing for people currently using it ]
and documented in detail _under GP_ as it currently stands.

That's section 2.7 (Errors & error recovery) of the manual (from CVS...).
Please check it out, and give suggestions for improvement !

>> In most cases we want to catch a specific error ( Exception: gegal and the
>> pipe testing code ).
>
> Today.  What if tomorrow you find another stuff to catch?

What do you mean ? I don't see what extra stuff you'd catch with your
proposed mechanism [ assuming pari_errno is available in both ].

Cheers,

    Karim.
-- 
Karim Belabas                    Tel: (+33) (0)1 69 15 57 48
Dép. de Mathematiques, Bat. 425  Fax: (+33) (0)1 69 15 60 19
Université Paris-Sud             Email: Karim.Belabas@math.u-psud.fr
F-91405 Orsay (France)           http://www.math.u-psud.fr/~belabas/
--
PARI/GP Home Page: http://www.parigp-home.de/