Skip to content

Worked Programs

Chris Michael edited this page Sep 2, 2026 · 2 revisions

Pudu

Worked Programs

These modules are small enough to read in one sitting and complete enough to pass pudu check. They favor one language idea at a time over framework-like scaffolding.

Propagating a recoverable failure

module Main

fn positive(value: Int) -> Result[Int, Str] {
  if value > 0 { Ok(value) } else { Err("expected a positive integer") }
}

fn doubled(value: Int) -> Result[Int, Str] {
  let checked = positive(value) ?
  Ok(checked * 2)
}

export fn main() -> Result[Int, Str] {
  let answer = doubled(21) ?
  print(show(answer))
  Ok(0)
}

positive owns the condition that can fail. doubled does not unpack and rebuild its Result; postfix ? returns the exact Err value to its caller and leaves the successful value in checked. main repeats that contract at the program boundary.

Describing a closed state space

module Main

type State = Waiting | Running(Int) | Finished{code: Int}

fn status(state: State) -> Str {
  match state {
    case Waiting => "waiting"
    case Running(step) if step > 0 => "running"
    case Running(_) => "starting"
    case Finished{code: 0} => "finished"
    case Finished{code: _} => "failed"
  }
}

export fn main() -> Int {
  print(status(Running(1)))
  0
}

The type declaration owns the possible states. The guarded Running arm does not cover the variant, so the following unguarded arm remains required. The two record patterns cover all Finished values.

Asking a set question

module Main

import Std.Set as Set

fn mayPublish(granted: Set[Str]) -> Bool {
  let required = setOf(["build", "publish"])
  Set.isSubsetOf(&required, &granted)
}

export fn main() -> Int {
  let granted = setOf(["read", "build", "publish"])
  if mayPublish(granted) { 0 } else { 1 }
}

The predicate reads in the same direction as the policy: every required capability must belong to the granted set. An array search would encode the representation of that question instead of its meaning.

A deterministic task tree

module Main

async fn work() -> Result[Int, Str] { Ok(1) }

export async fn main() -> Result[Int, Str] {
  async with scope {
    let value = work().await
    Ok(value)
  }
}

The call constructs a child task inside the scope and .await evaluates it. This example does not claim parallel execution: the current interpreter evaluates the task tree sequentially.

Checking the examples

Save one module as Main.pudu, then run:

pudu fmt --check Main.pudu
pudu check Main.pudu
pudu run Main.pudu

The wiki publication gate checks the formatter and checker forms. Runtime output is described only where it is part of the example's point.

Related

Clone this wiki locally