[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Scheme-reports] Exceptions on JVM [was: Exceptions needs examples]

On 1/5/2014 9:26 PM, Per Bothner wrote:
> This is a belated follow-up to a discussion about implementing
> r7rs exceptions on the JVM, and specifically:
> http://lists.scheme-reports.org/pipermail/scheme-reports/2012-March/001982.html
> FYI, I have implemented r6rs/r7rs-style exceptions on Kawa, roughly as
> suggested in the message above.  I originally implemented guard using
> the macro in R7RS, using with-exception-handler.  I also implemented
> a 'simple-guard' using the same syntax as 'guard', but using a cond
> inside a (native JVM) try-catch. (I used the guard-aux from r7rs.)
> This worked for the test/examples I've seen, but of course
> raise-continuable wouldn't get handled by a 'simple-guard'.
> So I implemented John Cowan's suggestion: Changed simple-guard
> to push a special mark (#!null) on the handler stack, and then
> just replaced guard by the simple-guard implementation.
> This implementation handles most test-cases - though not Hulmut
> Eller's more complex example with dynamic-wind (in the followup
> to the above-linked message).
> Performance will be a little slower than using "native" exception
> handling (try-catch, try-finally, and primitive-throw), but it shouldn't
> be too bad.  guard will normally be more efficient than
> with-exception-handler:
> guard is roughly a try-catch combined with a cond, though there is slightly
> more overhead than that.  (See the code in kawa/lib/exceptions.scm.)
> with-exception-handler will normally be able to inline the body 'thunk'
> (if it is a lambda expression), but it can't inline the handler.
> The source, if anyone is curious, is here:
> https://sourceware.org/viewvc/kawa/trunk/kawa/lib/exceptions.scm
> https://sourceware.org/viewvc/kawa/trunk/kawa/lib/ExceptionClasses.scm
Maybe how I implemented guard in Foment would work for Kawa as well.

For 'guard' to be really useful in real programs, it needs to be cheap, 
particularly for the normal case (no exception raised). The 
implementation in R7RS captures a continuation in the normal case and in 
Foment, capturing continuations is expensive: it requires a stack copy.

My solution is to make the dynamic environment explicit and separate 
from the continuation. When an exception is raised, unwind the dynamic 
environment to the 'guard' and execute the 'guard' clauses with the 
continuation of the 'raise'. If a clause returns, unwind the 
continuation to the 'guard'. If there is no 'else' clause, add one which 
will rewind the dynamic environment back to the handler and 
'raise-continuable' the exception.

The normal case is 'call-with-continuation-prompt', capture the dynamic 
stack, and 'with-exception-handler' all of which are cheap in Foment. 
The 'call-with-continuation-prompt' marks where to unwind to later if an 
exception is raised and it is handled by a clause.

The source is in https://code.google.com/p/foment/source/browse/src/base.scm

Scheme-reports mailing list