On Mon, Mar 2, 2009 at 3:48 PM, Peter Bex <peter....@xs4all.nl> wrote: > However, it turns out that an exception thrown in a thread simply > terminates the thread instead of unwinding the stack. The same does not > happen in the primordial thread:
> $ csi > #;2> (dynamic-wind (lambda () (print "BEFORE")) (lambda () (error "die!")) > (lambda () (print "AFTER"))) > BEFORE > Error: die! > AFTER Hi Peter. You might disagree with the rationale, but the behavior is in fact consistent--your example only happens to work at the REPL. Try compiling that or calling it with `csi -eval`, and you will see the after thunk is not invoked. When you are not at a REPL, the default error handler will immediately terminate the program upon error, or break into a repl if you've enabled that option; the after thunks are not invoked. When you *are* at a REPL, the default error handler is overridden to print an error message without terminating, and then the reset handler is called. The magic comes in when, before evaluating your expression, the REPL captures the current continuation and overrides the reset handler to invoke it. When an error occurs, that continuation is invoked to return to the REPL, *and* by doing so, your dynamic-wind after thunks are invoked. Note that this is exactly what Marc Feeley prescribed: "If the programmer knows how to recover from an exception, then he can capture the continuation early on, and install an exception handler which invokes the continuation. When the continuation is invoked the after thunks will execute." It just happens that at a REPL, exception recovery corresponds to "continue with the REPL". Here is a little program which demonstrates in essence what the repl is doing. Compile with `csc x.scm`. (define (simulate-repl thunk) (let ((eh (##sys#error-handler)) (rh (##sys#reset-handler))) (dynamic-wind (lambda () (##sys#error-handler (lambda (msg . args) (apply print "Error: " msg args)))) (lambda () (let ((k (call/cc (lambda (c) (##sys#reset-handler (lambda () (c #f))))))) (if k (thunk)))) (lambda () (##sys#error-handler eh) (##sys#reset-handler rh))))) (define (test) (dynamic-wind (lambda () (print "BEFORE")) (lambda () (error "die!")) (lambda () (print "AFTER")))) (simulate-repl test) (test) (test) ; not reached #| Output BEFORE Error: die! AFTER BEFORE Error: die! |# _______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org http://lists.nongnu.org/mailman/listinfo/chicken-users