Volume 12: Pattern Matching¶
1. Introduction¶
This volume defines pattern matching in the Rethon programming language. It describes the pattern matching model, match statements, case clauses, literal patterns, identifier patterns, wildcard patterns, enum case patterns, associated value patterns, struct patterns, type patterns, guard clauses, exhaustiveness checking, pattern bindings, pattern matching and scope, pattern matching and generics, pattern matching and protocols, pattern matching and error handling, future extensions, and summary.
This document is part of the official Rethon Language Specification. It is normative rather than descriptive. Implementations, tooling, documentation systems, and other source-processing tools shall treat the rules in this volume as authoritative.
This volume does not define backend lowering strategies, branch optimization details, or runtime-specific pattern-dispatch mechanisms. It defines the source-level and language-level behavior of pattern matching as readable control flow over typed values.
Rethon is Python-inspired in language philosophy and Python-first in surface syntax where practical. It uses static typing, enums as nominal value types, associated-value enums, structs as value types, protocols as behavior contracts, explicit exhaustiveness where practical, and readable source-level control flow.
Pattern matching shall be statement-based initially.
Pattern matching shall be designed for readable source code and static compile-time reasoning.
2. Pattern Matching Model¶
Pattern matching shall be a source-level control-flow form that selects a branch by comparing a matched value against one or more patterns.
Pattern matching shall support deconstruction of enum values, struct values, literal values, and type-constrained values according to the rules of this volume.
Example:
Pattern matching shall be statement-based initially.
An expression-based match form may be introduced later if the language decides that such a form improves clarity without weakening the existing statement-based model.
Pattern matching shall remain compatible with static typing, value-oriented design, and explicit source-level control flow.
3. Match Statements¶
A match statement shall inspect a matched value and select the first case clause whose pattern succeeds.
Example:
A match statement shall contain one matched expression and one or more case clauses.
A match statement shall use Python-like match and case syntax.
A match statement shall be a statement and shall not be required to produce a value.
A match statement shall be allowed wherever a statement is permitted by the language's block and scope rules.
A match statement shall respect indentation-based structure.
4. Case Clauses¶
A case clause shall contain a pattern and an associated body.
Example:
Case clauses shall be evaluated in source order unless a later language rule explicitly defines a different evaluation strategy for a specialized form.
The first matching case clause shall be selected.
A case clause may include a guard clause.
A case clause body shall be a block governed by ordinary indentation rules.
5. Literal Patterns¶
Literal patterns shall be supported.
Example:
A literal pattern shall match values equal to the literal under the language's ordinary equality and type rules.
Literal patterns shall be useful for simple branching on numbers, strings, booleans, characters, and other literal categories defined by the language.
Literal patterns shall remain statically checkable when the compiler can determine the relevant type information.
6. Identifier Patterns¶
Identifier patterns shall be supported.
An identifier pattern shall bind the matched value to a new pattern binding unless the identifier is interpreted as a special pattern keyword or value name by the language's pattern rules.
Example:
An identifier pattern shall introduce a binding that may be used in the case body.
An identifier pattern shall not require a prior declaration unless the language explicitly defines a different meaning for the identifier in that syntactic position.
An identifier pattern shall be useful when the programmer wants to capture the matched value rather than test for a specific constructor or literal.
7. Wildcard Patterns¶
Wildcard patterns shall be supported.
The wildcard pattern shall use _.
Example:
A wildcard pattern shall match any value and shall not bind the matched value to a name.
A wildcard pattern shall be useful for default cases and for ignoring values that are not needed in the case body.
The wildcard pattern _ shall not create a visible binding.
8. Enum Case Patterns¶
Enum case patterns shall be supported.
Example:
enum Direction:
north
south
east
west
match direction:
case Direction.north:
...
case Direction.south:
...
An enum case pattern shall match a value of the named enumeration case.
Enum case patterns shall be nominal and shall respect the enumeration declaration's type identity.
Enum case patterns shall work naturally with simple enumerations and with enumerations that carry associated values.
9. Associated Value Patterns¶
Associated value patterns shall be supported for enumeration cases that carry associated values.
Example:
enum Result:
success
failure(message: str)
match result:
case Result.success:
...
case Result.failure(message: message):
print(message)
Associated value patterns shall destructure the case's associated values into named pattern bindings or nested patterns.
Associated value patterns shall be statically typed.
Associated value patterns shall remain compatible with the language's value semantics and memory safety goals.
If an associated value pattern does not match the expected case shape, the case clause shall fail to match.
10. Struct Patterns¶
Struct patterns shall be supported.
Example:
struct Point:
x: int
y: int
match point:
case Point(x: 0, y: 0):
...
case Point(x: x, y: y):
print(x, y)
A struct pattern shall match a struct value by its declared fields.
Struct patterns shall be field-based and shall use field names in the source pattern.
Struct patterns shall support destructuring by named field, not by hidden storage layout.
Struct patterns shall remain compatible with the value semantics and field rules established elsewhere in the specification.
11. Type Patterns¶
Type patterns shall be supported.
A type pattern shall match a value only if the value satisfies the named type or type constraint permitted by the language's static rules.
Example:
A type pattern shall be useful when the matched value may have multiple statically known variants and the programmer wants to refine the type in a case body.
Type patterns shall remain compatible with value types, reference types, protocols, and generic instantiations where the language rules permit such matching.
Type patterns shall not weaken static typing.
12. Guard Clauses¶
Guard clauses shall be supported.
A guard clause shall add an additional boolean condition to a case clause.
Example:
A guard clause shall be evaluated only after its pattern successfully matches.
A case clause with a guard shall match only if both the pattern and the guard succeed.
Guard clauses shall be useful for refining otherwise broad patterns without introducing separate nested conditionals.
13. Exhaustiveness Checking¶
Exhaustiveness checking shall be required for enums where practical.
A match statement over a closed enumeration should ideally cover all cases or provide an explicit fallback case.
Example:
enum Direction:
north
south
east
west
match direction:
case Direction.north:
...
case Direction.south:
...
case Direction.east:
...
case Direction.west:
...
If the compiler can determine that a match over an enumeration omits one or more cases and no wildcard or equivalent fallback is present, the compiler shall diagnose the omission where practical.
Exhaustiveness checking shall support readability, safety, and maintainability.
The specification does not require exhaustiveness checking for every possible pattern form, but enumerations are a primary target for exhaustive reasoning.
14. Pattern Bindings¶
Pattern bindings shall be introduced by matching patterns that capture values.
Example:
A pattern binding shall be bound to the matched value or matched subvalue according to the pattern's structure.
Pattern bindings shall be visible in the case body corresponding to the successful match.
Pattern bindings shall not leak outside the case body.
Pattern bindings shall be subject to the language's type rules.
15. Pattern Matching and Scope¶
Pattern-bound names shall be scoped to the body of the matching case clause.
Example:
Names introduced by patterns shall not be visible in other case bodies or outside the match statement.
Pattern scopes shall remain readable and shall not introduce hidden cross-branch bindings.
Pattern matching shall not require the programmer to reason about partially visible bindings outside the selected case.
16. Pattern Matching and Generics¶
Pattern matching shall work with generic types where the language can determine the relevant type information.
Example:
enum Option<T>:
some(value: T)
none
match option:
case Option.some(value: value):
print(value)
case Option.none:
...
Generic pattern matching shall be statically checked.
A pattern involving a generic type shall be valid only when the compiler can confirm that the pattern is compatible with the scrutinee's type.
Pattern matching shall preserve type information where possible and shall not weaken the language's generic constraints.
17. Pattern Matching and Protocols¶
Pattern matching shall interact with protocols in a limited and explicit way.
A protocol may be used as a type pattern or in a later language-defined refinement form when the compiler can determine that the matched value satisfies the protocol contract.
Pattern matching shall not turn protocols into storage-bearing variants.
Protocols remain behavior contracts, and pattern matching shall respect that distinction.
If a later language rule introduces protocol-based matching refinements, those refinements shall remain statically checkable and explicit.
18. Pattern Matching and Error Handling¶
Pattern matching shall be useful for error handling and result handling.
Example:
enum Result:
success(value: int)
failure(message: str)
match result:
case Result.success(value: value):
print(value)
case Result.failure(message: message):
print(message)
Pattern matching shall make success and failure cases explicit in source code.
Pattern matching shall be suitable for result types, optional values, parse outcomes, and other closed-set control-flow modeling.
A fallback case may be used when a program intentionally ignores some variants or when exhaustive handling is not required by the specific control-flow context.
19. Future Extensions¶
This volume defines the current direction for pattern matching in Rethon, but future specification work may refine the model in carefully controlled ways.
Possible future extensions include:
- expression-based match forms
- nested destructuring refinements
- more expressive struct pattern syntax
- richer guard expressions or pattern combinators
- protocol-based refinement patterns if later justified
- additional exhaustiveness diagnostics for more type forms
- future tooling support for pattern-aware refactoring
Any future extension shall preserve the current direction:
matchandcaseare the core surface forms- pattern matching is statement-based initially
- enum matching is supported
- associated values are destructurable
- struct field matching is supported
_is the wildcard pattern- guards are supported
- pattern bindings are scoped to the selected case body
- exhaustiveness checking remains a design goal, especially for enums
20. Summary¶
Pattern matching shall be a statement-based source-level control-flow form in Rethon.
Rethon shall use Python-like match and case syntax.
Enum case matching, associated value destructuring, struct field patterns, wildcard patterns, guards, and scoped pattern-bound variables shall be supported.
Pattern matching shall work with generics where the compiler can determine the relevant type information.
Protocols may participate in pattern matching only in explicit and statically checkable ways.
Exhaustiveness checking shall be required for enums where practical.
Pattern matching shall therefore provide readable, static, and value-oriented control flow without exposing backend algorithm details.