(std syntax-match)

Reference

Overview

Pattern matching on syntax objects for macro transformers.

(import (std syntax-match))

(def/macro (my-let form inject compare)
  (syntax-match form
    ((_ ((name value) ...) body ...)
     #'((fun (,@name) ,@body) ,@value))
    (bad (syntax-error bad "my-let takes a binding list and a body."))))

#' constructs syntax and syntax-match destructures it. Use this macro instead of raw match on Syntax records.

A syntax-match form compiles into a single pattern match. Each clause becomes a pattern branch. Structural tests become pattern guards (#:when). Ellipses over compound patterns desugar into folds using all-of. See Docs/MACROS.org for comprehensive macro documentation.

See also: syntax-match, all-of

Reference

Functions

Macros

Functions

all-of

function ↑ Functions

(: all-of (-> (List %a) (-> %a (Option %b)) (Option (List %b))))
(all-of items f)

Applies a function across a list, returning all results or None if any element fails.

items
The list of items to process.
f
Transformation function returning (Some transformed) or None on failure.
returns
(Some results) in original order if f succeeds for every element, otherwise None.
(all-of (list 1 2 3) (fun (n) (if (> n 0) (Some (* n 2)) None)))   ; (Some (list 2 4 6))
(all-of (list 1 -2 3) (fun (n) (if (> n 0) (Some n) None)))        ; None

Used by syntax-match when expanding ellipses over compound patterns, such as ((name value) ...). Short-circuits on the first failure. Returns (Some (list)) for empty input.

See also: syntax-match

Macros

syntax-match

macro ↑ Macros

(syntax-match subject clause ...)

Matches a syntax expression against structural patterns, executing the first matching clause.

subject
Syntax expression to inspect, typically the macro input form.
clause ...
Clause specification (pattern body ...). Pattern variables are scoped within the clause body. The final expression determines the clause value.
(def/macro (swap! form inject compare)
  (syntax-match form
    ((_ a b)
     #'(let ((tmp ,a)) (set! ,a ,b) (set! ,b tmp)))
    (bad (syntax-error bad "swap! takes two variables: (swap! a b)."))))

;; 'else matches the identifier else; a keyword matches that keyword
(syntax-match clause
  (('else body ...) #'(begin ,@body))
  ((#:when test body ...) #'(when ,test ,@body))
  ((test body ...) #'(if ,test (begin ,@body) unit)))

Supported pattern forms:

_: Wildcard pattern; matches any syntax without binding.

name: Variable pattern; matches any syntax and binds it to name. Variable names must start with a lowercase letter. Uppercase names cause compile errors because they resemble union constructors; use quoted literals like 'Cons to match capitalized identifiers.

'name: Identifier literal; matches identifier name using syntax-ident=? (ignoring hygiene marks).

Literals: Integers, strings, characters, and keywords match exact literal values.

(p q): Fixed-length list pattern matching each sub-pattern positionally.

(p q ...): Variable-length pattern requiring initial matches for prefixes, with trailing elements matching q. If q is a variable, it binds remaining items as (List Syntax). If q is a compound pattern, inner variables bind lists of matched elements. Ellipses may nest: ((head arg ...) ...) binds head to a list and arg to a list of lists.

Restrictions: Only one ... is allowed per list pattern, and it must appear at the end. Duplicate variable bindings within a pattern are syntax errors.

Clauses evaluate in declaration order. If no clauses match and no wildcard/catch-all clause is present, a compile error is raised indicating that no clause matched. Provide a final fallback clause like (bad (syntax-error bad "...")) to generate informative macro errors.

See also: all-of