# Pattern Matching `match` is Deft's shape-based dispatch form. It deconstructs a value against a series of patterns and evaluates the right-hand side of the first match. Patterns support literals, bindings, type tests, map and list destructuring, guards, or-patterns, ranges, and regex. ## Quick Reference
match $value {
    42                           => "the answer"
    $x                           => "bound: $x"
    %Point{ :x $x }              => "point at x=$x"
    @{ $first & $rest }          => "first: $first"
    $n when ($n > 0)             => "positive"
    (1 | 2 | 3)                  => "low"
    1 .. 9                       => "single digit"
    %Err{ :message $m }         => "error: $m"
    _                            => "anything"
}
## Pattern Forms ### Wildcard `_` Matches anything, binds nothing:
match $v {
    _ => "default"
}
### Literal patterns Numbers, strings, booleans, keywords, and `nil` match by equality:
match $status {
    200    => "ok"
    404    => "not found"
    :error => "signalled"
    nil    => "nothing"
    _      => "other"
}
### Variable binding A bare `$name` matches anything and binds the value:
match $input {
    $x => echo "got: $x"
}
Reuse the same binding name in multiple branches to extract a value:
match $entry {
    @{ "name" $n } => $n
    %{ :name $n }  => $n
    _              => "(unknown)"
}
### Type patterns `%TypeName{ ... }` matches a tagged map by tag. Field destructuring is optional:
match $result {
    %Ok{ :value $v }      => $v
    %Err{ :message $m }   => [throw $m]
}

match $shape {
    %Point{}              => "a point"
    %Circle{}             => "a circle"
    _                     => "something else"
}
`%Type{}` matches the exact tag. To match a type and its subtypes or union variants, use the `^Type` type pattern (optionally binding with `^Type $name`):
defunion Shape << Circle | Square

match $shape {
    ^Shape $s   => "some shape"
    _           => "not a shape"
}
### Map patterns `%{ ... }` matches a plain map containing the listed keys (extra keys are fine):
match $user {
    %{ :first $f :last $l :age $a } => "$f $l, age $a"
    %{ :name $n }                   => $n
    _                               => "unknown"
}
### List patterns `@{ ... }` matches lists. `&` collects the rest:
match $xs {
    @{}                 => "empty"
    @{ $first }         => "one: $first"
    @{ $a $b }          => "two: $a, $b"
    @{ $a & $rest }     => "head: $a, rest has $rest(len) items"
}
### Guards (`when`) Add a condition to any pattern with `when`:
match $n {
    $x when ($x > 0)     => "positive"
    $x when ($x < 0)     => "negative"
    0                    => "zero"
}
### Or-patterns (`|`) Combine alternative patterns with `|` inside parens:
match $status {
    (200 | 201 | 204)    => "success"
    (401 | 403)          => "denied"
    _                    => "other"
}
### Ranges Numeric ranges match inclusive of both ends:
match $score {
    90 .. 100    => "A"
    80 .. 89     => "B"
    70 .. 79     => "C"
    _            => "F"
}
Ranges also compose with `Ok`/`Err` patterns:
match $result {
    %Ok{ :value (70 .. 80) } => "passed in band"
    _                        => "other"
}
### Negative patterns `not` excludes a sub-pattern:
match $user {
    %{ :role (not :admin) } => "user"
    %{ :role :admin }       => "admin"
    _                       => "?"
}
### Regex patterns `#"...":` matches a string against a PCRE2 regex:
match $line {
    #"^ERROR: (.+)$" => "error: $it"
    #"^WARN: (.+)$"  => "warning"
    _                => "other"
}
## First Match Wins Patterns are tried in order. The first match wins — put specific cases before general ones:
match $n {
    0           => "exactly zero"
    $x when ($x > 0)  => "positive"
    $x          => "negative"            # any remaining value
}
## Match Failure A `match` with no matching branch throws a runtime error. Always include a wildcard `_` fallback when the input space isn't fully covered:
match $input {
    %{ :type :click } => "clicked"
    %{ :type :hover } => "hovered"
    _                 => "ignored"
}
## Use Cases ### Command dispatch
def handle {|cmd args|
    match $cmd {
        "open"  => [open-file $args~path]
        "save"  => [save-file $args~path $args~content]
        "quit"  => [shutdown]
        _       => [throw "unknown command: $cmd"]
    }
}
### JSON decoding
def decode-user {|data|
    match $data {
        %{ :name $n :email $e } => %User{ :name $n :email $e }
        _                        => [throw "missing fields"]
    }
}
### State machines
def transition {|state event|
    match $state $event {
        :idle :start     => :running
        :running :pause  => :paused
        :paused :resume  => :running
        :running :stop   => :idle
        :paused :stop    => :idle
        _                => $state
    }
}
### Type-safe dispatch
def area {|shape|
    match $shape {
        %Circle{ :radius $r }    => ($math/pi * $r * $r)
        %Square{ :side $s }      => ($s * $s)
        %Rectangle{ :w $w :h $h } => ($w * $h)
    }
}
## Patterns Summary | Pattern | Matches | |---|---| | `_` | Anything | | `42`, `"hi"`, `:foo`, `nil`, `true` | Literal equality | | `$x` | Anything, binds the value | | `%Type{ :f $v }` | Tagged map with field | | `%Type{}` | Tagged map of given type | | `%{ :k $v }` | Plain map with key | | `@{}` | Empty list | | `@{ $a $b }` | List of exactly two | | `@{ $a & $rest }` | List with head and rest | | `1 .. 9` | Number in range (inclusive) | | `(a \| b \| c)` | Any of the alternatives | | `pat when cond` | Pattern plus guard | | `not pat` | Anything not matching | | `#"regex"` | String matching regex |