R6RS exceptions
Helmut Eller
eller.helmut@gmail.com
Sun Mar 16 16:41:00 GMT 2008
* Per Bothner [2008-03-15 23:43+0100] writes:
> Re-implementing guard becomes a bit tricky. The reference
> implementation uses call-with-current-continuation. That
> might work (it looks like it only needs the continuation
> support that kawa provides), but ugly and inefficient.
This is indeed tricky. R6RS says:
Evaluating a guard form evaluates <body> with an exception handler
that binds the raised object to <variable> and within the scope of
that binding evaluates the clauses as if they were the clauses of a
cond expression. That implicit cond expression is evaluated with the
continuation and dynamic environment of the guard expression. If every
<cond clause>'s <test> evaluates to #f 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.
Re-invoking raise in the original environment sounds difficult to do if
the tests should be evaluated in the environment of guard.
> If you want to try to get something based on these idea working,
> it would be much appreciated. Otherwise, I'll put it on my
> list, and try to get to it when I get a chance.
Well, I tried. Instead of evaluating the guard tests in the environment
of guard I evaluate them in the dynamic environment of the handler. The
<expressions> of the <cond clause> is evaluated in the environment of
guard. E.g.
(guard (c ((integer? c) 'int)
((pair? c) 'pair)
((vector? c) 'vector))
(raise x))
expands to something like this:
(let ()
(define handler
(lambda (c)
(let ((k
(cond ((integer? c) 0)
((pair? c) (+ 0 1))
((vector? c) (+ (+ 0 1) 1))
(else -1))))
(cond ((= k -1) (raise-continuable c))
(else (primitive-throw (<guard-matched> c k handler))))))
(try-catch
(parameterize
((current-exception-handlers (cons handler (current-exception-handlers))))
(raise x))
(ex
<guard-matched>
(if (eq? (slot-ref ex (quote handler)) handler)
(let ((c (slot-ref ex (quote condition))) (k (slot-ref ex (quote k))))
(cond ((= k 0) (quote int))
((= k (+ 0 1)) (quote pair))
((= k (+ (+ 0 1) 1)) (quote vector))))
(primitive-throw ex)))))
The implementation and some tests are attached below. Unfortunately I
get an nullpointer exception if I enable the module-export clause.
Helmut.
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: srfi34.scm
URL: <http://sourceware.org/pipermail/kawa/attachments/20080316/8a442609/attachment.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: r6rs-exceptions-test.scm
URL: <http://sourceware.org/pipermail/kawa/attachments/20080316/8a442609/attachment-0001.ksh>
More information about the Kawa
mailing list