compile/match

Symbol: compile/match

Syntax: (match SUBJECT [[PATTERN] BODY...] ... [else: BODY...])

Use-case: Structural pattern matching against one subject value. SUBJECT is evaluated once, then each arm’s pattern is tried in order. The first matching arm binds its captured names and runs its body, whose value is the result of the form. else: always matches; with no matching arm and no else: the form yields None. Pattern syntax is documented in Match patterns.

Behaviour: Requires at least one argument (SUBJECT). Each non-else clause is a list whose first element is the pattern delimiter – a list holding the pattern – and whose remaining elements are the body. The delimiter holds either a single pattern form ([[x]], [[5]], [[#[a b]]], [[Point[x y]]]) or the multi-token spelling of a typed pattern ([[x :: int]]); any other bare multi-token content raises SpecialError – a sequence is always the explicit #[...] / #(...) form, never bare juxtaposition.

An arm that does not match passes the subject to the next arm.

An arm’s pattern matches the subject as a single element. Every pattern kind may be an arm’s root, provided it can match one element; a root that cannot, such as the zero-width NOT head or a MATCH of two elements, raises SpecialError at compile time.

A clause may carry a guard between the delimiter and the body: [[PATTERN] when: COND BODY...] runs the body only when COND is truthy after the pattern binds; unless: inverts the sense. A failed guard advances to the next arm with the subject intact, and the bound captures persist (Python-consistent).

Name resolution, binding, sparse captures, and how sequence patterns test their elements are documented in Match patterns.

The head may be written as match or compile/match; compiler lookup resolves match to compile/match.

Expected lowered shape from layout/match:

(match SUBJECT
  [[PATTERN...] BODY...]
  [[PATTERN...] when: COND BODY...]
  [else: BODY...])

The layout wraps each case header into the clause delimiter, so the layout and s-expression forms produce identical clauses.

Examples:

;; sequence destructure with rest
(match data
  [[#[a b *: rest]] rest]
  [else: 0])
;; data = #(1 2 3)  ->  (3,)

;; whole-value typed capture, multi-token spelling
(match data
  [[x :: int] x]
  [else: "not an int"])
;; data = 7  ->  7

;; class pattern (subscript sugar) and guard
(match p
  [[Point[x y]] when: (> x y) "descending"]
  [[Point[x y]] "ascending-or-equal"]
  [else: "not a point"])

;; mapping with a literal and a bound key
(match msg
  [[#{"kind": "job" "url": u}] u]
  [[#{"kind": k}] k]
  [else: "other"])

;; extraction: call a function, destructure its result
(match path
  [[(app splitext #[base "." "ki"])] base]
  [else: path])

Also: layout handler match.