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

Concise SRFI34 problem

4 views
Skip to first unread message

Henrik Tidefelt

unread,
Feb 21, 2003, 7:55:16 PM2/21/03
to
Hi again,

I apologize for my last post, which was rather unstructured.

I have tracked down a very simple piece of code that illustrates the
problem:

>>>=================
(guard (ball
(#f (display "Caught exception."))) ; <-- Clause 1
(guard (ball
(#f (raise ball))) ; <-- Clause 2
(raise 'exn)))
<<<=================

The code above uses the reference implementation of SRFI34 (I only added
a (display "reraise") so that I can se when an exception is reraised due
to no matching guard clause).

As it stands, the evaluation goes into a reraise loop. The loop can be
broken by chaning the "#f" to "else" in either of the marked clauses.
By chaning in Clause 1 I get the output "Cauhgt exception.". By
changing Clause 2 I get the output "Unhandled exception: exn".

Why don't I get "Unhandled exception: exn" right away?


Thanks,

Henrik Tidefelt

Richard Kelsey

unread,
Feb 22, 2003, 11:58:47 AM2/22/03
to
Henrik Tidefelt <hent...@student.liu.se> wrote in message news:<henti634-608755...@newsc.telia.net>...

> >>>=================
> (guard (ball
> (#f (display "Caught exception."))) ; <-- Clause 1
> (guard (ball
> (#f (raise ball))) ; <-- Clause 2
> (raise 'exn)))
> <<<=================
[...]

> Why don't I get "Unhandled exception: exn" right away?

Because the reference implementation doesn't implement GUARD
properly. The description of GUARD says:

If every <clause>'s <test> evaluates to false and there is
no else clause, then raise is re-invoked on the raised object
within the dynamic environment of the original call to raise
*except that the current exception handler is that of the guard
expression*.

The GUARD implementation doesn't do the *'ed part at the end.
Sorry about that. I'll append a quick fix which works for your
example, at least.
-Richard Kelsey

(define (raise obj)
(really-raise obj *current-exception-context*))

(define (really-raise obj context)
(with-dynamic-environment
(exception-context-dynamic-env context)
(lambda ()
(with-exception-handler (lambda (exp)
((exception-context-previous-handler context)
exp))
(lambda ()
((exception-context-handler context) obj)
(error "handler returned"
(exception-context-handler context)
obj))))))

(define-syntax guard
(syntax-rules ()
((guard (var clause ...) e1 e2 ...)
((call-with-current-continuation
(lambda (k)
(let ((context *current-exception-context*))
(with-exception-handler
(lambda (var)
(let ((env (current-dynamic-environment)))
(k
(lambda ()
(let ((condition var))
(guard-aux (with-dynamic-environment env
(lambda ()
(really-raise
condition
context)))
clause ...))))))
(lambda ()
(call-with-values
(lambda () e1 e2 ...)
(lambda args
(k (lambda ()
(apply values args))))))))))))))

0 new messages