Computation
compute steps are the workhorse of mashin. They handle data transformation, calculation, formatting, and output construction. They use the mashin expression language (JavaScript-inspired) and are pure by construction: they cannot perform I/O, call external services, or access the network. This purity is not enforced by a sandbox. The capability simply does not exist.
Basic syntax
Section titled “Basic syntax”compute <name> <expression>The expression body is evaluated and its result becomes the step’s output. The last expression is the return value:
compute greet {greeting: "Hello, " + input.name + "!"}When to use compute
Section titled “When to use compute”Use compute when you need to:
- Transform data from inputs or previous steps
- Calculate values (totals, averages, scores)
- Build the final output of a machine
- Format or reshape data structures
- Apply conditional logic with ternary expressions
Do not use compute for anything that requires external interaction. Use ask ... using for LLM reasoning. Use ask ... from for calling other machines. Use action for HTTP, database, or file operations.
Using let bindings
Section titled “Using let bindings”Break complex expressions into readable steps with let:
compute analyze let items = input.orders.filter(o => o.status == "completed") let total = items.reduce((sum, o) => sum + o.amount, 0) let count = items.length let average = count > 0 ? total / count : 0 { completed_count: count, total_revenue: total, average_order: average, above_average: items.filter(o => o.amount > average).length }Each let binding is scoped to the current step.
Referencing previous steps
Section titled “Referencing previous steps”Access results from earlier steps with steps.<name>.<field>:
machine pipeline
accepts text as text, is required
responds with label as text score as number summary as text
behaves ask classify, using: "anthropic:claude-sonnet-4-6" with task "Classify this text: ${input.text}" returns category as text confidence as number
compute format let label = steps.classify.category let score = steps.classify.confidence { label: label, score: score, summary: label + " (confidence: " + score + ")" }
verifies test "formats the classification" assuming classify {category: "technology", confidence: 0.92} given {text: "New chip announced"} expect {label: "technology", score: 0.92}Conditional values
Section titled “Conditional values”Use the ternary operator for inline conditionals:
compute categorize let amount = input.amount { tier: amount > 10000 ? "enterprise" : amount > 1000 ? "business" : "starter", needs_review: amount > 5000, formatted: "$" + amount.toString() }For more complex branching, use a decide step instead. See Decisions.
Common patterns
Section titled “Common patterns”Combining results from multiple steps
Section titled “Combining results from multiple steps”compute combine_results { sentiment: steps.analyze_sentiment.label, topics: steps.extract_topics.topics, summary: steps.summarize.text, processed_at: now() }Filtering and mapping
Section titled “Filtering and mapping”compute filter_high_priority let urgent = steps.classify.items.filter(i => i.priority == "urgent") let names = urgent.map(i => i.name) { urgent_items: urgent, urgent_names: names, urgent_count: urgent.length }Building output from input
Section titled “Building output from input”compute normalize let cleaned = input.text.trim() let words = cleaned.split(" ").filter(w => w.length > 0) { original: input.text, cleaned: cleaned, word_count: words.length, preview: words.slice(0, 10).join(" ") + (words.length > 10 ? "..." : "") }Governance
Section titled “Governance”Compute steps are pure by construction (Law I). They:
- Never require governance approval
- Never appear in permission checks
- Always execute, regardless of trust level
- Are safe to run in any mode (full, test, simulate)
This is why a machine with only compute steps does not need an ensures section. There is nothing to govern.
Try it
Section titled “Try it”Write a machine that accepts a list of products (each with a name, price, and quantity). Use a single compute step to calculate the subtotal for each product, the overall total, the most expensive item, and the cheapest item. Use let bindings to keep the logic readable.
Next steps
Section titled “Next steps”- Expressions - Full expression language reference
- Decisions - When conditional logic needs more than ternary
- compute reference - Full specification