# Pattern matching


`matching/main.xo`

```xo
fn status_text(code: Int) -> Str {
  match code {
    200..=299 => "ok"
    429 | 503 => "retry later"
    404 => "not found"
    _ => "error"
  }
}

fn describe(xs: List[Int]) -> Str {
  match xs {
    [] => "empty"
    [x] => "one: ${x}"
    [first, .., last] => "from ${first} to ${last}"
  }
}

fn main(os: Os) {
  for c in [200, 503, 404, 500] {
    os.stdio.println("${c} ${status_text(c)}")
  }
  os.stdio.println(describe([]))
  os.stdio.println(describe([7]))
  os.stdio.println(describe([1, 2, 3]))
  let pair = (3, "three")
  let (n, word) = pair
  os.stdio.println("${n} ${word} ${pair is (3, _)}")
}
```

Output:

```text
200 ok
503 retry later
404 not found
500 error
empty
one: 7
from 1 to 3
3 three true
```



- Patterns include literals, ranges (`200..=299`), alternatives (`429 | 503`),
  list shapes (`[first, .., last]`), tuples, and enum variants with their
  fields.
- `let (n, word) = pair` destructures; `x is Pattern` tests without binding.

Every `match` must be exhaustive. Add a variant to an enum, and every `match`
that forgot it stops compiling:

```xo
enum Shape { Circle(r: Float), Rect(w: Float, h: Float), Point }

fn area(s: Shape) -> Float {
  match s {
    Circle(r) => 3.14 * r * r
    Rect(w, h) => w * h
  }
}

fn main(os: Os) { os.stdio.println("${area(Point)}") }
```

`xo check` says:

```text
main.xo:4:9: error XO0301: match on `Shape` is not exhaustive: missing `Point`
  note: add an arm for each missing case; matches must be exhaustive (core 2.3)
  fix: add the missing arms as holes
1 module(s), 1 error(s), 0 warning(s)
```


