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