Contents · The Flow Book

Start here

The Flow Book1. Your first run2. Let the outside answer3. Keep the original answer

Build the decision

4. Give the program an input5. Name the work6. Give values a shape

Build the workflow

7. Decide what failure means8. Put the decision in its own file9. Put the pieces together

Go further

10. Work on several things11. Leave room for an answer12. Take Flow into an application

Build an application

13. Investigate a real question14. Challenge: diagnose and extend
Language reference ↗

Decide what failure means

The pure decision is ready. Bring back the lookup. This time, handle the result instead of passing it straight to the caller.

Try it · Handle both replies
main.flow
use "./service"

pub flow main() -> Text = match service.lookup() {
    Ok(amount) => if amount > 100 { "Review" } else { "Proceed" },
    Err(problem) => { let _ = problem
        "Could not decide"
    },
}
service.flow
@tool pub flow lookup() -> Result<Int, Text>
Expected result"Proceed"

Take the result apart

match chooses a branch by the form of a value. In Ok(amount), the successful amount gets a name, and the branch makes our review decision. In Err(problem), the problem gets a name, and the branch explicitly returns "Could not decide".

let _ = problem explicitly drops the problem in this small example. In an application, you may want to preserve it in a typed outcome instead. Dropping it does not erase the recorded call or reply.

Explore more than success

Run the successful fixture. Then try declared failure, unknown outcome and a reply that remains pending. The first can produce a decision. The next two reach the error branch. Waiting has no reply to match yet, so it cannot choose either branch.

The exercise is not “make errors disappear.” Ask what the caller needs to know. A declared failure says the implementation reported failure. An unknown outcome says you cannot rely on a known outcome for the invocation. Those are different situations even when this introductory program returns the same message.

A failure value is still a value

A completed result containing an error is different from a runtime fault. Expected failures can be carried through ordinary data and handled by the program. A fault ends execution abnormally; it is not a successful return value you can pretend the program produced.

Later, ? and guard can shorten common patterns. Learn the explicit branches first so the shorter spelling has a meaning you can explain.

Exact rules: errors and ToolProblem, checking matches and discarded values.