Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

newbie exception handling question

5 views
Skip to first unread message

Donna

unread,
Sep 10, 2001, 3:56:47 AM9/10/01
to
I apologize if I am using any terminology incorrectly, but I have a question
that is really bugging me and I thought, if I don't ask I may never find the
answer.

I am wondering if there is anything in Lisp that acts as a try/catch
statement (or a way to construct such a thing) to catch and handle system
generated exceptions.

I am writing a genetic programming program that constructs random functions
that act on lists. In my fitness function I want to test this 'individual'
function, so I may end up with something like this:

(setf x '(1 2 3))
(rest (rest (first x)) ;randomly generated individual

of course this will produce an error/exception and that is what I want to
catch and handle gracefully, basically by giving this program a bad score
and exiting from the fitness function. Now I could write functions like
newrest, newfirst, etc and handle the case when the argument is not a list,
then when I find the best fit program change newrest to rest, etc. But that
seems awkward to me. I would really rather do something more elegant. I
would welcome any suggestions, ideas, and comments.

Donna

Christophe Rhodes

unread,
Sep 10, 2001, 4:02:46 AM9/10/01
to
Donna <donna...@mail.com> writes:

> I am wondering if there is anything in Lisp that acts as a try/catch
> statement (or a way to construct such a thing) to catch and handle system
> generated exceptions.

Yes -- all sorts of them.

As the bluntest saw, have a look at IGNORE-ERRORS; other things you'll
want to look at are HANDLER-BIND and/or HANDLER-CASE, and really you
should read about the whole of the condition system in Common Lisp.

Cheers,

Christophe
--
Jesus College, Cambridge, CB5 8BL +44 1223 510 299
http://www-jcsu.jesus.cam.ac.uk/~csr21/ (defun pling-dollar
(str schar arg) (first (last +))) (make-dispatch-macro-character #\! t)
(set-dispatch-macro-character #\! #\$ #'pling-dollar)

Donna

unread,
Sep 10, 2001, 4:18:56 AM9/10/01
to
Christophe Rhodes <cs...@cam.ac.uk> wrote in
news:sqae038...@lambda.jesus.cam.ac.uk:

> Donna <donna...@mail.com> writes:
>
>> I am wondering if there is anything in Lisp that acts as a try/catch
>> statement (or a way to construct such a thing) to catch and handle
>> system generated exceptions.
>
> Yes -- all sorts of them.
>
> As the bluntest saw, have a look at IGNORE-ERRORS; other things you'll
> want to look at are HANDLER-BIND and/or HANDLER-CASE, and really you
> should read about the whole of the condition system in Common Lisp.

Thank you Christophe!

I have come across HANDLER-BIND in my search so far, but it is beyond me at
this point, at least in the documentation in which I found it. Same with the
condition system. But now that I know that was the right track I will look
at other references, just to get a different view and to try to better
understand how to use them. And all the others you suggested are new to me,
so time to look them up :)

Thanks again!

Erik Naggum

unread,
Sep 10, 2001, 5:36:50 AM9/10/01
to
* Donna <donna...@mail.com>

> of course this will produce an error/exception and that is what I want to
> catch and handle gracefully, basically by giving this program a bad score
> and exiting from the fitness function.

If you wrap the entire function body in an ignore-errors form, it will
terminate upon encountering any errors at all and return two values: a
nil primary value and the error object as the secondary value, which you
are free to ignore, as well. This is a quick and painless exit from a
function with an error with the added bonus of returning "false". If you
need more scoring "resolution" than that, perhaps the calling function
can take care of it?

> Now I could write functions like newrest, newfirst, etc and handle the
> case when the argument is not a list, then when I find the best fit
> program change newrest to rest, etc. But that seems awkward to me. I
> would really rather do something more elegant. I would welcome any
> suggestions, ideas, and comments.

Common Lisp has a "safe mode" where all errors must be signalled. It
should be the default in your environment, but can be obtained with

(declaim (optimize (safety 3)))

In my experience, this is where implementations differ the most in
conforming, so it is hard to trust this requirement without talking to
other users of the same implementation. However, if you have more
knowledge than the system can intuit from what you are attempting to do,
you could write your own evaluator and examine this knowledge for
consistency before you get any errors.. This is not as hard as it seems.

///

Steven M. Haflich

unread,
Sep 10, 2001, 8:08:52 AM9/10/01
to

Erik Naggum wrote:
>
> Common Lisp has a "safe mode" where all errors must be signalled. It
> should be the default in your environment, but can be obtained with
>
> (declaim (optimize (safety 3)))

This is correct, but not the entire story. There are many situations
where the ANS does not require the implementation to detect and signal
a violation even in safe code. Often the standard is silent what
happens, meaning the result is undefined. The code might do something
reasonable, or might generate unreasonable results, or might signal
error just some of the time, or at worse, might so corrupt the running
Lisp world that continued computation is unreliable.

One such situation is division by zero. See ANS 12.2.27.

It is true that the ANS requires implementations to signal the example
Donna cites, passing a non-list to car or cdr, but Donna will have to
verify all the possible violations in her algorithms against the ANS
and also the behavior of the particular implementation. To "verify
all the possible violations" in a general Lisp function is not Turing
computable, but the prloblem might be computable in limited cases such
as those generated by the GA mutator.

Coby Beck

unread,
Sep 10, 2001, 10:05:55 AM9/10/01
to

"Donna" <donna...@mail.com> wrote in message
news:QH_m7.7833$ww1.7...@news02.tsnz.net...

The most straightforward is probably handler-case:

(setf x '(1 2 3))

(handler-case
(rest (rest (first x)))
(condition (c) ;; any error or condition object will be bound
to c (your choice of variable name)
(do-things-with-condition c) ;; perhaps describe it or log it or
examine it for scoring purposes
(do-other-stuff)
*failure*)) ;; return whatever means failure to you

This a simple catch-all way of using it. There are many amazing things you
can do with Lisp's condition handling system!

Coby
--
(remove #\space "coby . beck @ opentechgroup . com")


Tim Bradshaw

unread,
Sep 10, 2001, 10:28:03 AM9/10/01
to
* Coby Beck wrote:

> (handler-case
> (rest (rest (first x)))
> (condition (c) ;; any error or condition object will be bound
> to c (your choice of variable name)
> (do-things-with-condition c) ;; perhaps describe it or log it or
> examine it for scoring purposes
> (do-other-stuff)
> *failure*)) ;; return whatever means failure to you

I think that using CONDITION is probably not a good thing here. It
will cause the signalling of any condition at all to cause the handler
to be invoked, and this is probably not what you want (although it may
be). You *probably* want to handle only conditions which are errors.
Of course there are plenty of cases where you may want to handle other
conditions too, I'm just trying to generalise too much from inadequate
evidence..

--tim

0 new messages