Reraising continuations
Reraising errors/continuations caused me some serious head-scratching, but now it's complete. You can reraise errors from the guard handler, and the continuation will be reattached to the place where it's been taken from as if nothing has happened, and the stack unwinding will proceed from the current guard handler and up.
An example:
(fn main()
(println "one")
(println "two")
(error "three")
)
(guard main
(fn handler (err cont)
(if (task? err)
(reraise cont)
(println "caught error" err)
)))
Here, main
calls 2 functions that cause side-effects and raise continuations. But the guard handler checks if this is a task and just reraises it, pretending that the handler never happened. It only will return from the handler upon receiving an error.
The reraise
building block will be very important when I start implementing a better-looking try
macro. But for now it's already pretty convenient to be able to let the debug prints "fall through" the error handler.
Check out Valeri language if you're interested.