Re: Readability of exception handling

Parker Jones <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Message-ID <[email protected]>


A lot of helpful information so far.  And a tutorial on exception handling would definitely be a great help.

Still no examples of good exception handling though.  So here are a few snippets from the libraries which I presume are examples of good practice.

library/thread.pl:250
catch(thread_signal(Id, throw(abort)), _, true)

If there are any exceptions just catch them and do nothing.  Right?


library/thread.pl:379
solve(Goal, Var, Queue) :-
        thread_self(Me),
        (   catch(Goal, E, true)
        ->  (   var(E)
            ->  thread_send_message(Queue, done(Me, Var))
            ;   thread_send_message(Queue, error(Me, E))
            )
        ;   thread_send_message(Queue, failed(Me))
        ).

The pattern 
    (catch(_, Exception, true) -> (var(Exception) -> .. ; ..) ; .. )
occurs frequently in the libraries. Could someone explain how this works?  I understand there is no handler (just true/0) and then a check to see if Exception is instantiated.


library/statistics.pl:160
time(Goal) :-
        time_state(State0),
        (   call_cleanup(catch(Goal, E, (report(State0,10), throw(E))),
                         Det = true),
            time_true(State0),
            (   Det == true
            ->  !
            ;   true
            )
        ;   report(State0, 11),
            fail
        ).

An example with call_cleanup.  I find this really hard to read.  Is it just me?

I find this syntax more accessible:
try { }
catch(e1) { }
catch(e2) { }  
finally {  }

I don't suppose there is a way of writing exception handlers like this and translating to ISO compliant predicates?

Cheers,
Parker


> Date: Tue, 1 Apr 2014 08:29:55 -0700
> From: [email protected]
> To: [email protected]; [email protected]; [email protected]
> Subject: Re: [SWIPL] Readability of exception handling
> 
> >> Thanks for the reply, Alan.  But that is one handler that catches
> 
> >> only one exception. What about exception_1 with handler_1,
> >> exception_2 with handler_2,...?  Does that have a flat structure or
> >> does it require nesting?
> >
> >There is indeed a lot to say about proper exception handling in Prolog.
> >Too often (me too), we see code such as
> >
> >    catch(open(....), _, fail)
> >
> >which may fail because the file cannot be opened, but for zillions of
> >other reasons, such as wrong arguments to begin with or even some
> >resource error.  If anyone is aware of a good story that describes
> >best practices here, please provide a pointer.
> >
> >Some issues:
> >
>  >   - What error terms to throw from user code?
>  >   - When to catch errors and when test that you won't get one?
>  >   - When to use setup_call_cleanup/3 (instead)
>  >   - How to deal with one specific exception?
>  >   - How to deal with a variety of exceptions that may happen?
>  >   - How and when to use print_message/2
> >    - How to use library(prolog_stack)?
> >
> >This could make a great tutorial!  I'm happy to write some parts and
> >or comment!
> >
> >    Cheers --- Jan
> 
> My perspective is old-school C, and that exceptions are undesired complexity.
> 
> There are two reasons to throw:  
> a) When simple failure is insufficient information; you want to communicate the reason.
> b) When you want to short-circuit retries and escape up the stack.
> 
> [Aside, if your program has frequent exceptions, do not code 
> throw(my_exception(Info)), 
> but rather 
>         throw_my_exception(Info)
> where 
> throw_my_exception(ExceptionInfo) :- throw(my(ExceptionInfo)).
> 
> Because: you can put all your exceptions together in one spot where 
> they can be easily understood, standardized, and updated.
> ]
> 
> 
> There's really only two cases to catch:
> 
> a) The code you're invoking can throw for known reasons, and you want to react.  
> 
> Try plan A, catch an exception, try plan B.  (Plan B can be just fail.)
> b) Your code doesn't expect failure , and there's nothing to be done about it.  In this case,
> 
> you simply want the most informative message for the end user.  Having specific exception 
> types is irrelevant.  This handler is at the level of user input/response.  
> catch(Execute, AnyException, report(AnyException)).
> 
> setup_call_cleanup is for whenever the call has side-effects that need undoing.  
> 
> I know nothing of print_message or prolog_stack.  I do propose that no libraries should use 
> such unless during debugging, or when fatal errors occur.
> -------------- next part --------------
> HTML attachment scrubbed and removed
> _______________________________________________
> SWI-Prolog mailing list
> [email protected]
> https://lists.iai.uni-bonn.de/mailman/listinfo.cgi/swi-prologb

 		 	   		  
-------------- next part --------------
HTML attachment scrubbed and removed
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.