Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

match: Pattern Matching

Type-safe pseudo pattern matching on AST node tags.

Syntax

match ast {
  Tag1 = handler1;
  Tag2 = handler2;
  _ = defaultHandler;
}

Each handler is a function that receives the matched node.

Examples

Simple Match

match ast {
  Sym = n: n.contents;
  _ = n: "unknown";
}

Destructure

match ast {
  App = { func, arg }: "application";
  If = { cond, thenExpr, elseExpr }: "conditional";
  Let = { bindings, body }: "let expression";
  _ = n: n.tag;
}

Nested Match

match ast {
  Set = { recursive, bindings }:
    if recursive then "recursive set" else "set";
  _ = n: "other";
}

Handler Signatures

Each handler receives the node as its argument. You can destructure the fields:

# Full node
match ast {
  Sym = n: n;  # n is the entire node
  _ = n: n;
}

# Destructured
match ast {
  Sym = { contents }: contents;  # destructure fields
  App = { func, arg }: func;
  _ = n: n.tag;
}

Wildcard

The _ handler catches any unmatched tag:

match ast {
  Sym = n: "symbol";
  _ = n: "other: ${n.tag}";
}

Use Cases

Type Checking

isInteger = match ast {
  Constant = { contents }: syntax.isInt contents;
  _ = _: false;
};

Pretty Printing

pretty = match ast {
  Sym = { contents }: contents;
  Int = { contents }: toString contents;
  Str = { contents }: "\"${contents}\"";
  _ = n: builtins.toJSON n;
};