Skip to content

Lesson 5: Module 05: Control Flow and Loops

Chain steps together, branch conditionally, and build iterative pipelines.

Learning Objectives

  • Organize steps into named flows (a named sequence of steps)
  • Use multiple flows for organization and control
  • Branch with decide steps for conditional routing
  • Iterate with control flow patterns

Complexity Ladder: Levels 2-4 (Conditional, Iterative, Resilient); branching, loops, and error handling.

The Concept: Controlling the Flow

Until now, our machines have been linear: Step A, then Step B, then Step C. Real workflows need branching (“if this, do that”), routing (“send billing issues here, support issues there”), and iteration (“process each item”). Mashin provides all of these through chains and control flow constructs.

Think of chains as chapters in a recipe book. The main chapter (:main) is your starting point. You can reference other chapters (run) — follow those instructions, then come back. Or you can jump to a chapter (goto) — like “start over from step 1” without coming back.

Chains are named sequences of steps. Every machine has at least one flow — :main — which is the entry point. You can define additional chains for organization, error handling, or looping.

Here is how run (call-and-return) and goto (tail-call / jump) differ visually:

run flow(:process) goto flow(:iterate)
(Call-and-return) (Tail-call / jump)
flow :main flow :iterate
┌─────────────────┐ ┌─────────────────┐
│ step :setup │ │ step :work │
│ │ │ │ │ │
│ ▼ │ │ ▼ │
│ run :process ───┼──► flow :process │ goto :iterate ──┼──┐
│ │ │ (runs, then │ │ │
│ ▼ │ returns here) │ step :never_runs│ │
│ step :finalize │ │ (unreachable!) │ │
└─────────────────┘ └─────────────────┘ │
▲ │
└──────────────┘
(loops back)

Notice that run returns to the calling flow so the next step (:finalize) can execute, while goto jumps away permanently — any steps after it are unreachable.

Start With Koda

Koda requires a free account. Sign in or create an account to use Koda exercises throughout this course. If you’re not signed in yet, read on; the exercises will be here when you’re ready.

Ask Koda:

“Build a machine that processes a list of URLs. For each URL, fetch the content and summarize it. If a fetch fails, skip that URL and continue with the next one.”

Check that Koda uses for_each (iterate over each item in a list) for iteration and proper error handling. The machine should use loop(:item) (access the current element in a for_each loop) inside the for_each block to access each URL.

Chains and Chain Control

Multiple Chains

machine processor "Pipeline Processor"
accepts
data as string, is required
responds with
result as map
implements
flows
flow main
compute validate
{valid: length(input.data) > 0}
ask process_data, using: "anthropic:claude-haiku-4"
with task "Process this data: ${input.data}"
returns
output as map
compute finalize
{result: steps.process_data.output}
flow process
ask process_data, using: "anthropic:claude-haiku-4"
with task "Process this data: ${input.data}"
returns
output as map

run vs goto

These two control flow primitives have critically different behavior:

Multiple flows are used for organization and modularity.

Conditional Execution

decide Steps

Use decide steps for conditional routing:

decide route_by_severity
when steps.check.severity == "critical"
ask alert, from: "@mashin/actions/http/post"
url: "https://alerts.example.com/critical"
otherwise
compute log_info
{logged: true}

Branching Patterns

decide process_or_reject
when steps.validate.valid == true
ask process, using: "anthropic:claude-haiku-4"
with task "Process: ${input.data}"
otherwise
compute reject
{error: "Invalid input", rejected: true}

Multi-Way Routing

Route execution based on a value:

decide route_by_format
when input.output_format == "summary"
ask summarize, using: "anthropic:claude-haiku-4"
with task "Summarize: ${input.text}"
when input.output_format == "structured"
ask extract, using: "anthropic:claude-sonnet-4"
with task "Extract structured data from: ${input.text}"
returns
entities as list
topics as list
otherwise
compute passthrough
{result: input.text}

Building It: Multi-Step Pipeline with Branching

A document processor that validates, routes by format, and handles errors:

machine document_pipeline "Document Pipeline"
accepts
document as string, is required
format as string
responds with
result as map
format_detected as string
implements
compute validate
{valid: length(input.document) > 10}
ask detect_format, using: "anthropic:claude-haiku-4"
with task "What format is this document? Options: markdown, json, plain.\n\n${input.document}"
returns
format as string
compute resolve_format
{format: input.format != "auto" ? input.format : steps.detect_format.format}
decide route_by_format
when steps.resolve_format.format == "json"
compute process_json
{result: {type: "json", parsed: true}, format_detected: "json"}
when steps.resolve_format.format == "markdown"
ask process_markdown, using: "anthropic:claude-haiku-4"
with task "Extract headings and structure from this markdown:\n${input.document}"
returns
headings as list
sections as number
otherwise
ask process_plain, using: "anthropic:claude-haiku-4"
with task "Summarize this plain text document:\n${input.document}"
returns
summary as string

Key Syntax

// Flow definition (under implements)
implements
flows
flow name
// steps go here
// Single flow (implicit, no flows wrapper needed)
implements
compute step_a
{result: "done"}
// Decide step for branching
decide name
when condition
// steps for this branch
otherwise
// fallback steps

Common Mistakes

  1. Overcomplicating control flow. Keep flows linear when possible. Use decide steps only when you need conditional routing based on runtime values.

  2. Infinite loops without limits. Always include a check-and-exit condition for iterative flows. The flow depth limit (100) will catch runaway loops, but your logic should stop before that.

What’s Next

In Module 06, you’ll combine everything from Modules 01-05 to build a full ReAct (Reason-Act-Observe) agent, the loop pattern that powers autonomous AI systems.