-
-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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.
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.
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.
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.
Save one module as Main.pudu, then run:
pudu fmt --check Main.pudu
pudu check Main.pudu
pudu run Main.puduThe wiki publication gate checks the formatter and checker forms. Runtime output is described only where it is part of the example's point.
- Modules And Imports
- Values, Bindings, And Blocks
- Types And Inference
- Records, Sums, And Tuples
- Functions Generics And Traits
- Pattern Language
- Control Flow And Patterns
- Iteration And Loops
- Failure And Propagation
- Numbers And Collections
- Sets Maps And Sequences
- Keyed Structures
- Trees And Hierarchies
- Standard Library
- Output Formatting And Testing
- Tasks And Scopes
- Compile-Time Evaluation
- Typed Macros
- References And Unsafe
- Worked Programs