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