fallible ergonomics

This commit is contained in:
2026-06-30 20:32:13 +02:00
parent 07c560b750
commit 7ca7e33033
8 changed files with 289 additions and 25 deletions
+12 -10
View File
@@ -576,10 +576,12 @@
merge/conflict/widening/rejections and the `.Yield` inference regression
- deferred follow-ups are split below; 23.5 keeps the next user-visible slice small
23.5. fallible ergonomics: catch blocks + composable try widening
- implement `expr catch |e| { ... }` with `e : E`
- allow `try` to widen `T ! E1` into an enclosing `T ! (E1 | E2)` channel
- add focused tests/examples for both
23.5. fallible ergonomics: catch blocks + composable try widening (implemented)
- `expr catch |e| { ... }` binds `e : E` in the handler and uses the existing value-block
`yield` rules to produce the fallback success value
- `try` still requires the same success type `T`, but now propagates either the exact error
channel or a sum-widenable `E1` into an enclosing `E1 | E2`
- focused coverage lives in `examples/programs/errors` and the fallible ergonomics compiler test
- leave ABI/layout/lint/design polish for later milestones
23.6. contextual payload construction + inline error types
@@ -974,7 +976,7 @@ message :: match code {
Brolang handles errors as values. There is no hidden control flow — a function that can fail declares this in its signature, and the caller must explicitly handle the possibility of failure.
Milestone 23 v1 implements named error channels, native sum composition, `return`-based error dispatch, exact-channel `try`, and fallback `catch`. It intentionally defers the `error` keyword shorthand, inline error types, `catch |e|` blocks, and `try` widening across different-but-composable error channels.
Milestone 23 v1 implements named error channels, native sum composition, `return`-based error dispatch, exact-channel `try`, and fallback `catch`. Milestone 23.5 adds `catch |e|` blocks and `try` widening across composable error channels. It still defers the `error` keyword shorthand, inline error types, contextual payload construction, and match-on-error shorthand.
### Fallible Functions
@@ -1093,11 +1095,11 @@ process func(path []u8) Ast ! ProcessError {
}
```
In v1, `try` propagates only when the callee's error channel exactly matches the enclosing function's error channel. Widening narrower error types into a composed return channel is a planned follow-up.
`try` propagates when the success type matches the enclosing fallible function and the callee's error channel either exactly matches or can widen into the enclosing composed error channel.
### Handling with `catch`
The `catch` keyword handles errors and provides a value to continue with. Milestone 23 v1 implements the fallback-value form.
The `catch` keyword handles errors and provides a value to continue with. It supports both fallback values and block handlers.
**Provide a fallback value:**
@@ -1105,7 +1107,7 @@ The `catch` keyword handles errors and provides a value to continue with. Milest
data :: read_file(path) catch default_data
```
**Planned block form using** `yield` (deferred in v1):
**Block form using** `yield`:
```
data :: read_file(path) catch |e| {
@@ -1156,9 +1158,9 @@ data :: read_file(path) catch |e| match e {
| `return e` | Exit function via error channel when `e : E` |
| `error e` | Planned shorthand, not v1 |
| `error .variant{...}` | Planned shorthand, not v1 |
| `try expr` | Unwrap success or propagate an exact matching error channel |
| `try expr` | Unwrap success or propagate an exact/sum-widenable error channel |
| `expr catch fallback` | Provide fallback value on error |
| `expr catch |e| { ... }` | Planned block handler, not v1 |
| `expr catch |e| { ... }` | Bind `e : E` and yield a fallback value from the handler |
| `yield value` | Provide value from innermost block |
| `yield :label value` | Provide value from labeled block |
| `return` / `return value` | Exit the current function; in fallible functions, return value dispatches by type |