Result records that a function can either return a value or one of its
expected errors. Check success before you use the value. On failure, handle
the error locally or let it return to the caller.
A value or a failure
A function that can fail returnsResult(Success, Failure). The first type is
the successful value. The second type is the error. The failure type must belong
to the Error family.
After placeOrder returns a Result, continue only on success:
- Forst
- Generated Go
ensure order is the same as ensure order is Ok(). On failure, the function
that contains this ensure returns order’s error (except in main and Go
tests). After the check, order is the successful value.
See Return a named error for how to declare the
failure types, and Check a value for short forms of
ensure.
How a function gets that type
Forst can infer this return type whenensure introduces a failure path.
- Forst
- Generated Go
reserve can fail, so Forst infers Result(Int, Error). The
caller uses ensure reserved is Ok() before using the successful value.
A function with no success value that still has a failure path (body ensure
with no success return) infers Result(Void, Error). Generated Go writes that
as func() error. Callers treat the binding like other Results
(ensure result or ensure result is Ok()).
Ok() and Err() identify the two sides of a Result during is and
ensure checks. They are checks. General Ok(value) and Err(error)
constructors are still in development.
Bare ensure order is Ok() with no else gives the caller a Result return
type (except main / Go tests) and returns the error from order. Use
if order is Ok() when you want local handling without changing the caller’s
return type.
Let Forst infer the return type
Forst looks at three places when a function has no declared return type.- Each explicit
return - Each
ensurethat can fail - The final expression in the function body
return.
- Forst
- Generated Go
g returns Result(Int, Error). The final call to g() means that f
returns the same type. Generated Go contains return g().
Use an explicit return whenever it makes the intent easier to see.
Stay in the function on failure
Useif when failure should not return from the function. Forst refines the
value inside the matching branch. Outside the branch, order is still the
full Result:
- Forst
- Generated Go
Check which error you got
UseErr(ErrorName) when each error needs a different response. First declare
a closed list of errors:
- Forst
- Generated Go
- Forst
- Generated Go
result is a ParseFailed. See
List alternatives
for error unions.
Handle Go functions with several returns
Go functions often return a value and an error. Forst preserves all returned values when you capture the call in one variable. The resulting type is aTuple.
Split the values and check the error when your Forst function should return a
Result.
err has type Error, the missing
else returns that error. Writing ensure !err else err remains valid
but is redundant.
Result and Tuple stay separate
The two types make different promises. AResult contains one outcome. It is
either a success or a failure. A Tuple preserves every returned position, and
several positions may contain meaningful values at the same time.
Why Forst never turns several returns into a Result automatically
Why Forst never turns several returns into a Result automatically
Result means that you get a value or an error. Some calls can return both.
For example, a read can return its final bytes together with an end of input
signal. The bytes still need to be processed.Forst cannot learn this behavior from the return types. A pair containing a
value and an error looks the same in both cases. Keeping a list of special
calls would miss new packages and functions.Forst therefore never turns several return values into a Result
automatically. This keeps Ok() and Err() trustworthy. Ok() always means
that there is no error. Err() always means that there is no success value.- A call with several returns always becomes a
Tuplewhen captured in one value. Every returned value stays available. - A
Resultcomes from a function with exclusive success and failure paths.returnandensuremake those paths explicit. - Conversion between
TupleandResultis unavailable.Ok()andErr()only apply toResult. - When you know a call has exclusive outcomes, split its values and use
ensure !errbefore returning the success value. - The rule applies to every package. It needs no catalog or project setting.
Tuple. Split the values as shown above when you
want a Result.For calls used only for side effects, prefer Forst println or print. A
Provider contract method can also declare an explicit
return type.Use errors from TypeScript
Generated TypeScript clients can expose error payloads as tagged shapes. This part of the client API is still evolving. Generate the client withforst generate and see Generate client types
for the current output.
Caveats
Result is experimental. Check the
roadmap before relying on edge cases in production.
Failure side
The failure type must belong to theError family. Other failure types are not
supported yet.
Ok and Err role
Ok and Err support is and ensure checks. General value constructors are
still in development.
Final Go calls
A final Go call with several return values produces aTuple during return
inference. Split the values and check the error when you need a Result.
For limits around ensure order is Ok(), see
Check a value.
Examples
See the Result examples on GitHub:examples/in/result_ensure.ftexamples/in/result_void_ensure.ftexamples/in/result_unwrap_propagate.ftexamples/in/result_if.ftexamples/in/union_error_types.ft
Related
Return a named error
Declare and return named failures.
Check a value
How ensure connects checks to control flow.
List alternatives
Closed sets of named errors.