RFC Example: Enhanced Pattern Matching Syntax
Note: This is an example RFC template, demonstrating how to write a complete RFC proposal. Please refer to this template when writing your own RFC.
Status: Example (for reference only)
Author: Chenxu (example author) Creation Date: 2025-01-05 Last Updated: 2026-02-12
Summary
Add more powerful pattern matching capabilities to YaoXiang, including nested patterns, guard expressions, and let pattern bindings.
Motivation
Why is this feature needed?
The current match expression has limited functionality and cannot handle the following common scenarios:
yaoxiang
# Cannot destructure nested structures
Person: Type = { name: String, address: Address }
Address: Type = { city: String, zip: Int }
match person {
Person(name: "Alice", address: Address(city: "Beijing", _)) => "Alice from Beijing" # ❌ Not supported
}
# Cannot bind variables in patterns
match result {
ok(value) => print(value) # ❌ Requires explicit destructuring
}Current Problems
- Nested pattern destructuring is not supported
- Guard expressions cannot be used in patterns
letstatements do not support pattern matching
Proposal
Core Design
Extend the match expression syntax to support:
- Nested pattern destructuring: Struct destructuring at any depth
- Guard expressions: Add
ifconditions after patterns - Pattern variable binding: Bind variables directly from patterns
Examples
yaoxiang
# Nested destructuring
Person: Type = { name: String, address: Address }
Address: Type = { city: String, zip: Int }
match person {
Person(name: "Alice", address: Address(city: "Beijing", _)) => "Alice from Beijing"
Person(name: n, address: Address(city: c, _)) => n + " from " + c
}
# Guard expressions
match n {
n if n > 0 and n < 10 => "1-9"
n if n >= 10 => "10+"
_ => "unknown"
}
# Pattern binding
match result {
ok(value) => print(value) # value is already bound
err(e) => log_error(e)
}
# Nested + binding
match data {
User(name: first, profile: Profile(age: a)) if a >= 18 => first + " is adult"
}let Statement Pattern Matching
yaoxiang
# New syntax
let Point(x: 0, y: _) = point # Only binds when x == 0
let Ok(value) = result # Destructures Result
# Multiple bindings
let (a, b, c) = tuple # Destructures tupleDetailed Design
Syntax Changes
MatchExpr ::= 'match' Expr '{' MatchArm+ '}'
MatchArm ::= Pattern ('|' Pattern)* ('if' Expr)? '=>' Expr ','
Pattern ::= LiteralPattern
| IdentifierPattern
| StructPattern
| TuplePattern
| OrPattern
| RestPattern
LiteralPattern ::= '_' | Literal
IdentifierPattern ::= Identifier (':' Pattern)?
StructPattern ::= Identifier '(' FieldPattern (',' FieldPattern)* ','? ')'
FieldPattern ::= Identifier ':' Pattern | Identifier
TuplePattern ::= '(' Pattern (',' Pattern)* ','? ')'
OrPattern ::= Pattern '|' Pattern
RestPattern ::= '...'Type System Impact
- Type checking for pattern matching needs to be extended
- Pattern variables obtain the correct type when matching succeeds
Compiler Changes
| Component | Changes |
|---|---|
| lexer | Add pattern-related tokens |
| parser | Add pattern parsing logic |
| typecheck | Pattern type inference and binding |
| codegen | Pattern matching code generation |
Backward Compatibility
- ✅ Fully backward compatible
- Only adds new syntax; existing
matchsyntax remains unchanged
Trade-offs
Advantages
- More expressive syntax, more concise code
- Consistent with mainstream language pattern matching (Rust, Scala, Elixir)
- Reduces runtime errors, catches mismatches earlier
Disadvantages
- Increased compiler implementation complexity
- Slight increase in learning curve
Alternatives
| Alternative | Why Not Chosen |
|---|---|
| Top-level destructuring only | Cannot handle common nested scenarios |
| Functional style | Awkward to mix with imperative code |
| Defer to v2.0 | Users already have strong demand |
Implementation Strategy
Dependencies
- No external dependencies
- Requires the base type system to be completed first
Risks
- Pattern compilation complexity may cause performance issues
- Deep nesting may cause stack overflow
Open Questions
- [ ] Syntax for circular patterns (
@binding)? - [ ] Support compile-time pattern exhaustiveness checking?
- [ ] Performance optimization strategy?
