36 lines
1.3 KiB
Markdown
36 lines
1.3 KiB
Markdown
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.
|