Result values. Each variant has a name and payload in Go’s “errors as values” style.
Nominal errors
Declare named failure kinds with payloads:- Forst
- Generated Go
ensure … or …:
- Forst
- Generated Go
Simple payload example
A minimal nominal error with one payload field:- Forst
- Generated Go
Result types
Functions that can fail with typed errors returnResult(Success, Failure). The failure side is constrained to the Error family today.
- Forst
- Generated Go
Ok and Err serve as discriminants for is / ensure. They are not yet general value constructors for building Result values at every call site.
Return inference and implicit returns
Forst infers a function’s return type from:- explicit
returnstatements ensure(often producingResult(S, Error)when no return type is declared)- the last expression in the function body when no return type is declared in the signature
return for it.
- Forst
- Generated Go
f also returns Result(Int, Error); generated Go contains return g().
Explicit return is still fine (and clearer when intent is ambiguous):
- Forst
- Generated Go
Trailing calls and Go imports
This differs from Go statement semantics. A trailing call whose Go signature is(T, error) is typed in Forst as Result(T, Error) when its result is used — including as an implicit return:
- Forst
- Generated Go
logAndReport returns Result(Int, Error), not void. To log for side effects only, use Forst println / print, or declare a void return on a Provider contract method.
Go interop
Forst folds Go’s(T, error) returns into Result(T, Error) at the boundary where wired. Generated Go uses idiomatic error returns. Your ops team still reads familiar code.
Generate client types
Nominal errors can emit tagged shapes in generated.d.ts as the TS story matures. Today, prefer forst generate and treat error payloads as evolving. See Generate client types.
Compared to Go error structs
In Go you might write:error Name { … } syntax makes the intent explicit: this is a failure variant, a dedicated type for a specific failure mode rather than a generic struct with an Error() method attached by convention.
Caveats
Nominal errors andResult are experimental. Check the roadmap before relying on edge cases in production.
Result failure side
The failure type parameter is constrained to the Error family today. Arbitrary non-Error failure types are not supported yet.
Ok and Err role
Ok and Err are discriminants for is and ensure. They are not general value constructors at every call site yet.
Implicit return trap
When a function has no declared return type, a trailing Go call that returns(T, error) can make the whole function return Result(T, Error). That includes fmt.Println and similar calls. Use println for void side effects, or declare an explicit return type.
Nominal errors incomplete
ensure only failure authoring, or LUB rules, and TypeScript _tag export are still maturing. Treat generated error payloads as evolving. See Generate client types § Caveats.
For ensure x is Ok() narrowing limits, see Ensure and narrowing § Caveats.
Try it
From the Forst repository:Related
Ensure and narrowing
How
ensure connects checks to control flow.