ensure with is to validate at runtime and narrow types. Forst has no exceptions. Coercion is never silent.
Basic ensure
Reject invalid input at runtime and attach a domain error withor:
- Forst
- Generated Go
ensure x is Condition: runtime check; failure returns or propagates an error depending on contextor …: attach a domain-specific failure when the condition does not hold
is operator for built-in constraints (LessThan, Min, Present, Ok, …).
Nil and presence
Forst usesNil for absence checks today. Full optional value types (T | Nil) are still planned; what works now is nil on nilable types (pointers, Map, Array, Error), ensure … is Nil(), and *T .Present() / .Nil() on pointer fields.
- Forst
- Generated Go
- Forst
- Generated Go
Result and Ok narrowing
Map lookups and other partial operations yieldResult(V, Error) instead of comma-ok tuples:
- Forst
- Generated Go
v, ok := m[k]) is not Forst syntax. Handle failure explicitly with ensure avail is Ok() before using the success value.
At call sites, narrow success payloads:
- Forst
- Generated Go
If-branch narrowing
if x is … can refine a variable’s type inside the branch. That helps when you need conditional logic instead of early return:
- Forst
- Generated Go
Compared to Go and TypeScript
Forst requires
ensure with English keywords so validation stays visible in the source.
Caveats
ensure and narrowing are experimental. Behavior and diagnostics are still maturing. See the roadmap.
Checks run once
A successfulensure or if check narrows the type for following lines. The compiler does not watch the value for later changes. Reassignment or field mutation can leave runtime state out of sync with the narrowed type.
See Type guards § Checks run once for a concrete example with guards.
Simple names
Successor narrowing afterensure works best on simple identifiers (ensure x is …, then use x).
Compound paths like ensure req.state is … have partial support. Hover may show the predicate, but the typechecker does not fully re-register a refined type on the path.
After if chains
Narrowing inside an if branch does not always carry past the end of the chain. The continuation may see the pre-if type until union types exist. Branch merge after ensure successors is also still expanding.
No comma-ok
v, ok := m[k] is not Forst syntax. Map lookups and similar partial operations return Result(V, Error). Use ensure avail is Ok() before using the success value.
Optionals still partial
Full optional value types (T | Nil) are planned. Today use nil on nilable types, ensure … is Nil(), and *T .Present() / .Nil() on pointer fields.
What gets emitted
Ensure statements lower to Go error returns and conditionals. Failures are structured values returned through Go’s error path. Custom failures use nominal error types when you provide them withor.
Try it
From the Forst repository:Related
Errors and Result
Nominal error types and structured failures.
Type guards
User-defined predicates for domain rules.