<!-- Sema documentation — Pattern Matching & Interpolated Literals
     Sema is a new AI-native, neurosymbolic programming language most models
     have not been trained on. Full corpus: https://sema.49.12.246.95.sslip.io/llms-full.txt
     Install language support: https://sema.49.12.246.95.sslip.io/install-skill/ -->

# Pattern Matching & Interpolated Literals

> match/case over structs, enums, tuples, and regex captures — with guards, or-patterns, exhaustiveness — plus f-strings and typed SQL templates.

`match`/`case` is Sema's structural branching construct. It destructures values,
binds their parts, checks guards, and — where the domain is finite — verifies that
you handled every case. Case order is explicit and there is **no fallthrough**.
This page also covers **interpolated literals** (f-strings, regex literals, and
typed SQL templates), because they interlock with matching.

## The pattern forms

| Pattern | Example | Matches |
|---|---|---|
| Wildcard | `case _:` | anything |
| Literal | `case 0:`, `case "fee":` | that exact scalar/string |
| Bind | `case x:` | anything, binding it to `x` |
| Bind + guard | `case x if p(x):` | anything for which the guard holds |
| Struct | `case Money(currency=c, minor_units=m):` | that struct, binding fields |
| Enum | `case Escalation.page(oncall, deadline):` | that variant, binding payload |
| Tuple | `case (a, b):` | a 2-tuple, binding elements |
| Regex | `case re"^FEE (?P<n:int>[0-9]+)$":` | a string matching the pattern |
| Or-pattern | `case Ok(x) \| Cached(x):` | either alternative |

## Matching enums and their payloads

Enum variant payloads destructure positionally or by name. Enum `match` is
**exhaustiveness-checked** — if you miss a variant, `sema check` tells you:

```sema
enum Escalation:
    none
    notify(channel: str)
    page(oncall: str, deadline: Duration)

match esc:
    case Escalation.page(oncall, deadline): dispatch(oncall, deadline)
    case Escalation.notify(channel):        post(channel)
    case Escalation.none:                   pass
```

## Matching `Option` and `Result`

Because there is no `null`, you consume `Option`/`Result` by matching — it is the
exhaustive way to handle presence and failure:

```sema
match choose_assignment(incident, resources):
    case Some(assignment): commit(assignment)
    case None:             defer(incident)

match load_rows(path):
    case Ok(rows):  reconcile(rows)
    case Err(e):    quarantine(path, evidence=e)
```

## Structs and tuples

Struct patterns bind fields by name; a **field subset is legal**, and positional
struct patterns are **forbidden** (fields are named, not ordered). Tuple patterns
destructure positionally:

```sema
match price:
    case Money(currency=c, minor_units=m) if m > 0: settle(c, m)
    case Money(minor_units=0):                      skip()      # field subset

match pair:
    case (0, y): on_y_axis(y)
    case (x, 0): on_x_axis(x)
    case (x, y): interior(x, y)
```

## Guards

A `case … if <guard>:` arm only matches when the guard also holds. Guards can be
ordinary expressions — or a **semantic predicate**, which types the branch as
`statistical(α)` and requires monitor coverage like any semantic decision site:

```sema
match memo:
    case text if semantics("memo describes a chargeback", text, alpha=0.02):
        return ChargebackMemo(raw=text)
    case _:
        return UnknownMemo(raw=memo)
```

See [/neurosymbolic/verification/](/neurosymbolic/verification/) for how
`semantics(...)` guards are calibrated and monitored.

## Or-patterns

`P1 | P2` matches either alternative. Both alternatives must **bind the same names
at the same types**, and exhaustiveness accounts for the union:

```sema
match result:
    case Ok(v) | Cached(v): use(v)      # both bind `v: T`
    case Err(e):            report(e)
```

## Refutable vs irrefutable patterns

- An **irrefutable** pattern always matches — it is used for destructuring
  *assignment*: `a, b = pair`, `Money(currency=c, minor_units=m) = price`.
- A **refutable** pattern may fail to match — it belongs in a `match`. A refutable
  pattern in assignment position is a **compile error** directing you to `match`.

```sema
a, b = pair                                       # ok: irrefutable
Money(currency=c, minor_units=m) = price          # ok: irrefutable destructure
# Some(x) = maybe_user                            # error: refutable — use match
```

## Exhaustiveness

Enum and struct patterns are **exhaustiveness-checked where the domain is finite**.
Regex and string cases are not exhaustiveness-checkable, so they **require a
wildcard `case _:`** at `assure silver` and above. There is no fallthrough — each
case is independent and ordered top to bottom.

## Interpolated literals

Interpolated string literals are **typed templates**, not string concatenation.

### f-strings

`f"…"` returns `str` with segment provenance. The result's trust label is the meet
of all interpolated values and the literal text — so tainted data stays tainted
through interpolation:

```sema
summary = f"latest={latest.major}.{latest.minor} top={top.name}"
bullet  = f"- {self.item}"
```

### `validate <expr>:` — a contract boundary on a composed value

`validate <expr>:` introduces a local contract boundary where `value` names the
constructed candidate. This is the one-line validator hook for composed strings and
templates:

```sema
notice = validate f"Case {case_id}: {summary}":
    sem "Analyst-facing case notice"
    ensure len(value) <= 240
    check semantics("notice contains no raw account numbers or secrets", value, alpha=0.01)
```

### Regex literals and typed captures

Regex literals use `re"…"` and are **compiled at build time**. Named captures bind
locals in `match` cases, and a capture may declare a **deterministic parser** with
`(?P<name:Type>…)` — the compiler lowers this to a regex capture plus a typed
boundary parse, so a **failed parse makes the case not match** (it is a non-match,
never an exception):

```sema
match memo:
    case re"^ACH CREDIT (?P<counterparty>[A-Z0-9 .-]+) REF (?P<ref>[A-Z0-9-]+)$":
        return PaymentMemo(counterparty=counterparty, reference=ref)
    case re"^FEE (?P<minor_units:int>[0-9]+) (?P<currency>[A-Z]{3})$":
        return FeeMemo(amount=Money(currency=parse_currency(currency),
                                    minor_units=minor_units))
    case _:
        return UnknownMemo(raw=memo)
```

### Typed SQL templates

`sql"…"` returns a typed `SqlQuery`, **not** `str`. Interpolation holes are bound
**parameters** by default (never string-spliced), so injection is structurally
impossible. Identifier and fragment interpolation are separate, explicit
capabilities (`sql.ident(trusted_name)`, `sql.fragment(validated_fragment)`), and a
raw string cannot be executed as SQL:

```sema
query = validate sql"""
    select id, amount_minor, currency, memo
    from ledger_entries
    where tenant_id = {tenant_id}
      and booked_epoch_s >= {start_epoch_s}
    order by booked_epoch_s desc
""":
    sem "Read-only tenant-scoped ledger lookup"
    ensure sql.read_only(value)
    ensure sql.has_parameter(value, "tenant_id")
    check semantics("query cannot read outside the requested tenant", value, alpha=0.01)
```

Query execution adds `db.read`, `db.write`, or `db.schema` to the caller's effect
row and policy envelope — the dialect, schema, row type, and effect are inferred
from the connection or declared explicitly.

## Failure modes

- **Non-exhaustive enum/struct match** → `sema check` error listing the missing cases.
- **Regex/string match without a wildcard** → `assure silver` failure.
- **Refutable pattern in assignment position** → compile error, directing to `match`.
- **Or-pattern alternatives binding different names/types** → compile error.
- **Raw string used where `SqlQuery` is required, or user identifier without
  endorsement** → compile error / policy denial.
- **Semantic guard in a case** → types the branch `statistical(α)`, needs monitor
  coverage.

## See also

- [Control Flow](/language/control-flow/) — `if`/`for`/`while`/`with`/`loop … until`.
- [Traits, Enums & Generics](/language/traits-enums-generics/) — declaring the enums you match.
- [Error Handling](/language/error-handling/) — `expect`/`except`, `?`, and combinators.
- [Verification](/neurosymbolic/verification/) — calibrating `semantics(...)` guards.
