sigildocs

(sigil match)

(sigil match) - Pattern Matching

Destructure and dispatch on data using patterns. Match values against shapes, bind variables, and combine patterns with guards, boolean logic, and transformations.

Basic Usage

(import (sigil match))

;; Destructure a list
(match '(1 2 3)
  ((a b c) (+ a b c)))  ; => 6

;; Type dispatch
(match value
  ((? number?) "it's a number")
  ((? string?) "it's a string")
  (_ "something else"))

Pattern Types

PatternDescription
_Wildcard, matches anything
()Empty list
'datumLiteral value (uses equal?)
#t / #fBoolean literals
(p1 . p2)Pair: p1 matches car, p2 matches cdr
(p1 p2 ...)List: each element matched positionally
varVariable binding
(? pred)Guard: matches if (pred val) is true
(? pred pat)Guarded pattern: pred and pattern must both match
(and p ...)All patterns must match
(or p ...)Any pattern matches (first wins)
(not pat)Negation: matches if pattern doesn't
(= proc pat)Transform: apply proc, then match result
($ type p ...)SRFI-9 record: match type tag and fields positionally
(: type k: ...)Sigil struct: match by keyword fields
#{ k: p ... }Dict: match by keyword fields
#(p ...)Vector: match elements positionally

Guard Patterns

Use (? predicate) to match values satisfying a condition:

(match x
  ((? positive? n) (format "positive: ~a" n))
  ((? negative? n) (format "negative: ~a" n))
  (_ "zero"))

Combining Patterns

Use and, or, and not to combine patterns:

;; All conditions must match
(match n
  ((and (? integer?) (? positive?)) "positive integer")
  (_ "other"))

;; Any condition can match
(match color
  ((or 'red 'green 'blue) "primary")
  (_ "other"))

;; Negation
(match lst
  ((not ()) "non-empty")
  (() "empty"))

Transform Patterns

Use (= proc pat) to transform a value before matching:

(match str
  ((= string-length 0) "empty")
  ((= string-length 1) "single char")
  (_ "multiple chars"))

Record Patterns (SRFI-9)

Use ($ type fields ...) to match SRFI-9 record types positionally:

(define-record-type <point>
  (make-point x y) point?
  (x point-x) (y point-y))

(match p
  (($ <point> x y) (+ x y)))

Struct Patterns (Sigil)

Use (: type field: ...) to match Sigil structs by field name:

(define-struct point (x) (y))

(match p
  ((: point x: y:) (+ x y))        ; shorthand: binds x and y
  ((: point x: px y: py) ...))     ; explicit binding names

;; Match only specific fields
(match p
  ((: point y:) y))                ; only match y field

Dict Patterns

Use #{ key: pat ... } or (dict key: ...) to match dicts by key:

(match config
  (#{ host: port: } (connect host port))  ; explicit bindings required
  ((dict debug:) debug))                   ; shorthand with (dict ...)

;; Type check only
(match val
  ((dict) 'is-dict)
  (_ 'other))

Exports

matchsyntax

Match a value against patterns and execute the matching clause.

Each clause has the form (pattern body ...). Patterns are tried in order until one matches, then its body is executed. See the module documentation for the full list of pattern types.

;; Basic destructuring
(match '(1 2 3)
  ((a b c) (list c b a)))  ; => (3 2 1)

;; With wildcards
(match '(1 2 3 4 5)
  ((first _ third . rest) (list first third rest)))
; => (1 3 (4 5))

;; Literal matching
(match cmd
  ('quit (exit))
  ('help (show-help))
  (('load file) (load-file file))
  (_ (unknown-command)))

Create an anonymous function that pattern-matches its argument.

Equivalent to (lambda (x) (match x clause ...)).

(define get-x (match-lambda ((x . _) x)))
(get-x '(1 2 3))  ; => 1

(map (match-lambda
       ((a b) (+ a b))
       (_ 0))
     '((1 2) (3 4) (5)))
; => (3 7 0)

Create an anonymous function that pattern-matches all its arguments.

The argument list is matched as a single pattern. Useful for multi-argument destructuring.

(define add-pair
  (match-lambda* ((a b) (+ a b))))
(add-pair 3 4)  ; => 7

((match-lambda*
   ((x) x)
   ((x y) (+ x y))
   ((x y z) (+ x y z)))
 1 2 3)  ; => 6
match-letsyntax

Bind variables using pattern matching.

Like let, but each binding uses a pattern instead of a simple variable.

(match-let (((x y) '(1 2))
            ((a . b) '(3 4 5)))
  (list x y a b))
; => (1 2 3 (4 5))