knazarov.com/content/posts/reraising_continuations/note.md

37 lines
1.3 KiB
Markdown
Raw Permalink Normal View History

X-Date: 2024-10-15T22:54:31Z
X-Note-Id: e2abd2ec-c537-4e15-a4a1-7eb374d48a06
Subject: Reraising continuations
X-Slug: 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](https://git.knazarov.com/knazarov/valeri) if you're interested.