๐Ÿฆ€ Functional Rust
๐ŸŽฌ Pattern Matching Exhaustive match, destructuring, guards, let-else โ€” compiler-verified branching.
๐Ÿ“ Text version (for readers / accessibility)

โ€ข match is exhaustive โ€” the compiler ensures every variant is handled

โ€ข Destructuring extracts fields from structs, tuples, and enums in one step

โ€ข Guards (if conditions) add extra logic to match arms

โ€ข if let and let-else provide concise single-pattern matching

โ€ข Nested patterns and @ bindings handle complex data shapes elegantly

589: Command Dispatch with Enums

Difficulty: 3 Level: Intermediate Represent commands as enum variants and dispatch them with match โ€” type-safe, extensible, and testable.

The Problem This Solves

String-based command dispatch is the quick way out: `match cmd.name { "set" => ..., "remove" => ..., _ => unknown }`. It compiles regardless of what strings you have. Add a new command? Hope you don't typo. Rename a command? Grep-and-pray. The `_` arm silently swallows anything unrecognized. HashMap-based dispatch (function pointers or boxed closures indexed by string) is slightly better for extensibility, but the types get messy and the commands themselves can't carry typed payloads. A `"set"` command needs a key and a value; how do you pass those safely through a `HashMap<String, fn(...)>`? Enum command dispatch solves both. Each command is a variant that carries its own payload โ€” strongly typed, named, checked by the compiler. Adding a new command means adding a variant and an arm; the compiler points you to every match that needs updating. No magic strings, no type erasure.

The Intuition

Think of the command enum as a type-safe message protocol. `Cmd::Set(key, value)`, `Cmd::Increment(key, delta)`, `Cmd::Remove(key)`, `Cmd::Clear`. Each variant encodes exactly what the command needs, no more, no less. The executor is a match: "what shape is this command? do the right thing." The match is also the audit log โ€” you can see every command the system handles at a glance. No dynamic dispatch, no virtual functions, no trait objects needed. An important bonus: pure replay. Store the commands as a `Vec<Cmd>`. Replay them with `fold` over an empty state. You get an event-sourcing architecture for free โ€” the history is the state. OCaml's functional approach naturally supports this with immutable stores.

How It Works in Rust

#[derive(Debug, Clone)]
enum Cmd {
 Set(String, i64),
 Remove(String),
 Increment(String, i64),
 Clear,
}

#[derive(Debug, Default)]
struct Store {
 data: HashMap<String, i64>,
 history: Vec<Cmd>,
}

impl Store {
 fn execute(&mut self, cmd: Cmd) {
     // Dispatch on variant โ€” each arm handles one command
     match &cmd {
         Cmd::Set(k, v)        => { self.data.insert(k.clone(), *v); }
         Cmd::Remove(k)        => { self.data.remove(k); }
         Cmd::Increment(k, d)  => { *self.data.entry(k.clone()).or_default() += d; }
         Cmd::Clear            => { self.data.clear(); }
     }
     self.history.push(cmd);  // record every command
 }
}

// Pure command application โ€” no side effects, returns new state
fn apply(mut data: HashMap<String, i64>, cmd: &Cmd) -> HashMap<String, i64> {
 match cmd {
     Cmd::Set(k, v)       => { data.insert(k.clone(), *v); }
     Cmd::Remove(k)       => { data.remove(k); }
     Cmd::Increment(k, d) => { *data.entry(k.clone()).or_default() += d; }
     Cmd::Clear           => { data.clear(); }
 }
 data
}

// Replay history from scratch โ€” event sourcing
let final_state = store.history
 .iter()
 .fold(HashMap::new(), |acc, cmd| apply(acc, cmd));

What This Unlocks

Key Differences

ConceptOCamlRust
Command type`type cmd = Add of string * int \...``enum Cmd { Set(String, i64), ... }`
Dispatch`let execute store = function \Add(k,v) -> ...``match cmd { Cmd::Set(k,v) => ... }`
Mutable stateImmutable store + new value returned`&mut self` โ€” mutate in place
Pure replayNatural โ€” fold over immutable commands`fn apply(data, cmd) -> data` โ€” explicit pure form
HistoryFunctional: list of commands is natural`Vec<Cmd>` in the store struct
use std::collections::HashMap;

#[derive(Debug,Clone)]
enum Cmd {
    Set(String, i64),
    Remove(String),
    Increment(String, i64),
    Clear,
}

#[derive(Debug,Default)]
struct Store {
    data: HashMap<String,i64>,
    history: Vec<Cmd>,
}

impl Store {
    fn execute(&mut self, cmd: Cmd) {
        match &cmd {
            Cmd::Set(k,v)       => { self.data.insert(k.clone(), *v); }
            Cmd::Remove(k)      => { self.data.remove(k); }
            Cmd::Increment(k,d) => { *self.data.entry(k.clone()).or_default() += d; }
            Cmd::Clear          => { self.data.clear(); }
        }
        self.history.push(cmd);
    }

    fn get(&self, k: &str) -> Option<i64> { self.data.get(k).copied() }
}

// Pure command executor (no side effects)
fn apply(mut data: HashMap<String,i64>, cmd: &Cmd) -> HashMap<String,i64> {
    match cmd {
        Cmd::Set(k,v)       => { data.insert(k.clone(), *v); }
        Cmd::Remove(k)      => { data.remove(k); }
        Cmd::Increment(k,d) => { *data.entry(k.clone()).or_default() += d; }
        Cmd::Clear          => { data.clear(); }
    }
    data
}

fn main() {
    let mut store = Store::default();
    let cmds = vec![
        Cmd::Set("x".into(), 1),
        Cmd::Set("y".into(), 2),
        Cmd::Increment("x".into(), 9),
        Cmd::Remove("y".into()),
        Cmd::Set("z".into(), 3),
    ];
    for cmd in cmds { store.execute(cmd); }
    let mut keys: Vec<_> = store.data.keys().collect();
    keys.sort();
    for k in keys { println!("{}={}", k, store.data[k]); }
    println!("history len={}", store.history.len());

    // Pure replay
    let final_state = store.history.iter().fold(HashMap::new(), |acc, c| apply(acc, c));
    println!("x={:?}", final_state.get("x"));
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test] fn set_get() {
        let mut s = Store::default();
        s.execute(Cmd::Set("k".into(),42));
        assert_eq!(s.get("k"), Some(42));
    }
    #[test] fn increment() {
        let mut s = Store::default();
        s.execute(Cmd::Increment("n".into(),1));
        s.execute(Cmd::Increment("n".into(),2));
        assert_eq!(s.get("n"), Some(3));
    }
}
(* Command pattern in OCaml *)
type cmd =
  | Add    of string * int
  | Remove of string
  | Set    of string * int
  | Clear

type store = (string * int) list

let execute store = function
  | Add(k,v)    -> (k,v) :: List.filter (fun (k',_)->k'<>k) store
  | Remove k    -> List.filter (fun (k',_)->k'<>k) store
  | Set(k,v)    -> (k,v) :: List.filter (fun (k',_)->k'<>k) store
  | Clear       -> []

let () =
  let cmds = [Add("x",1);Add("y",2);Set("x",10);Remove("y");Add("z",3)] in
  let store = List.fold_left execute [] cmds in
  List.iter (fun (k,v)->Printf.printf "%s=%d\n" k v) store