Skip to content

Patternia v0.5.3 Release Note

Release Date: December 14, 2025 Version: 0.5.3


Overview

Patternia v0.5.3 introduces advanced pattern matching capabilities with guard predicates, enhanced binding mechanisms, structural decomposition patterns, and range matching utilities. This release significantly expands the expressiveness of pattern matching while maintaining zero-overhead performance and type safety.


New Features

Enhanced Binding Patterns (bind() and bind(subpattern))

Enhanced: bind() function with subpattern support for conditional binding.

// Basic binding - captures the subject itself
match(value)
    .when(bind() >> [](auto x) { /* use x */ })
    .end();

// Binding with subpattern - first matches subpattern, then captures subject
match(number)
    .when(bind(lit(42)) >> [](auto x) { /* x is 42, subject is also captured */ })
    .when(bind([](auto n) { return n > 0; }) >> [](auto subject, auto n) {
        return fmt::format("positive: {} (subject: {})", n, subject);
    })
    .otherwise("non-positive");

Key Capabilities: - bind() - Captures the subject itself as a single-element tuple - bind(subpattern) - First matches with subpattern, then captures both subject and subpattern bindings - Type-safe binding with compile-time validation - Integration with all existing pattern types

Guard Predicates and Placeholder Expressions

Added: Comprehensive guard system with placeholder _ and predicate combinators.

// Placeholder-based guard expressions
match(number)
    .when(bind()[_ > 10 && _ < 100] >> "two-digit")
    .when(bind()[_ >= 100] >> "three-or-more-digits")
    .otherwise("single-digit");

// Range predicates with different modes
match(value)
    .when(bind()[rng(0, 10)] >> "small closed")           // [0, 10]
    .when(bind()[rng(10, 20, open)] >> "medium open")    // (10, 20)
    .when(bind()[rng(20, 30, open_closed)] >> "large open-closed") // (20, 30]
    .when(bind()[rng(30, 40, closed_open)] >> "xlarge closed-open") // [30, 40)
    .otherwise("out of range");

// Lambda guards for complex conditions
match(data)
    .when(bind()[[](auto x) { return x.is_valid() && x.size() > 0; }] >> "valid")
    .otherwise("invalid");

Guard Features: - _ placeholder for creating comparison expressions (_ > 10, _ == 42, etc.) - rng() function for range predicates with four modes: closed, open, open_closed, closed_open - Predicate combinators: && (logical AND) and || (logical OR) - Lambda guard support for complex custom conditions - Type-safe guard predicate evaluation

Structural Decomposition Patterns (has<>)

Added: has<&T::field...>() for aggregate and struct decomposition.

struct Point { int x, y; };
struct Circle { Point center; int radius; };

// Basic field presence checking
match(point)
    .when(has<&Point::x, &Point::y> >> "valid point")
    .otherwise("invalid point");

// Combining with binding for field access
match(circle)
    .when(has<&Circle::center, &Circle::radius> >> bind() >> [](auto c) {
        return fmt::format("circle at ({}, {}) with radius {}", 
                           c.center.x, c.center.y, c.radius);
    })
    .otherwise("invalid circle");

// Multi-level structural matching
match(complex_data)
    .when(has<&Data::points> >> bind()[[](auto pts) { return !pts.empty(); }]
         >> [](auto data, auto pts) {
        return fmt::format("data with {} points", pts.size());
    })
    .otherwise("empty or invalid data");

Structural Pattern Features: - Compile-time validation of member pointer parameters - Support for multiple field pointers in single pattern - Integration with binding patterns for field access - Zero-overhead struct decomposition - Type-safe member access checking

Advanced Pattern Composition

Enhanced: Seamless integration between all pattern types.

// Complex pattern combining all features
match(data)
    .when(
        has<&Data::value, &Data::status> >> 
        bind()[[](auto d) { return d.value > 0; } && [](auto d) { return d.status == Status::Active; }]
     >> [](auto d, auto value, auto status) {
        return fmt::format("active data: {} (status: {})", value, status);
    })
    .when(
        has<&Data::value> >> 
        bind([](auto v) { return v < 0; })[_ > -100]
     >> [](auto subject, auto v) {
        return fmt::format("negative value: {} (subject: {})", v, subject);
    })
    .otherwise("no match");

Internal Improvements

Pattern Framework Extensions

Enhanced: Advanced pattern matching infrastructure: - Guard predicate evaluation system - Enhanced binding pattern composition - Structural pattern validation - Type-safe predicate combinators

Type System Improvements

Added: Comprehensive type support for: - Member pointer validation in has<> - Guard predicate type detection - Binding contract forwarding - Template parameter deduction

Performance Optimizations

Maintained: Zero-overhead guarantees: - Compile-time guard predicate evaluation where possible - Inlined pattern matching - Optimal struct field access - Efficient tuple composition for binding


Architecture Changes

Guard System Architecture

Added: Comprehensive guard framework: - guard_predicate_tag for type detection - placeholder_t with comparison operator overloads - binary_predicate for standard comparisons - range_predicate with configurable modes - guarded_pattern wrapper for pattern composition

Enhanced Binding System

Expanded: Binding pattern capabilities: - binding_pattern for subject capture - binding_as_pattern for subpattern composition - Tuple concatenation for multi-value binding - Forwarding binding contracts to inner patterns

Structural Pattern Framework

Added: Member pointer-based decomposition: - Compile-time member pointer validation - has_pattern for field presence checking - Integration with existing pattern ecosystem - Zero-overhead field access


Usage Examples

Guard with Placeholders

match(score)
    .when(bind()[_ >= 90] >> "excellent")
    .when(bind()[_ >= 80 && _ < 90] >> "good")
    .when(bind()[_ >= 70 && _ < 80] >> "average")
    .otherwise("needs improvement");

Range Matching with Different Modes

match(temperature)
    .when(bind()[rng(18.0, 22.0)] >> "comfortable")           // [18, 22]
    .when(bind()[rng(22.0, 30.0, open)] >> "warm")            // (22, 30)
    .when(bind()[rng(30.0, 40.0, open_closed)] >> "hot")      // (30, 40]
    .when(bind()[rng(-10.0, 18.0, closed_open)] >> "cool")   // [-10, 18)
    .otherwise("extreme temperature");

Structural Pattern with Guards

struct Employee {
    std::string name;
    int age;
    double salary;
    bool active;
};

match(employee)
    .when(
        has<&Employee::age, &Employee::salary, &Employee::active> >>
        bind()[[](auto e) { return e.active && e.age >= 25; }]
     >> [](auto e, auto age, auto salary, auto active) {
        return fmt::format("active employee: {} ({} years, ${:.2f})", 
                          e.name, age, salary);
    })
    .when(
        has<&Employee::age> >>
        bind([](auto age) { return age < 25; })[_ >= 18]
     >> [](auto subject, auto age) {
        return fmt::format("young employee: {} years old", age);
    })
    .otherwise("no match");

Complex Pattern Composition

match(container)
    .when(
        has<&Container::size> >>
        bind()[[](auto c) { return c.size() > 0; } && [](auto c) { return c.size() <= 100; }]
     >> [](auto c, auto size) {
        return fmt::format("container with {} items", size);
    })
    .when(
        has<&Container::size> >>
        bind()[[](auto c) { return c.size() == 0; }]
     >> [](auto c) {
        return "empty container";
    })
    .otherwise("large or invalid container");

Bug Fixes

Pattern Validation

Fixed: Edge cases in pattern matching: - Guard predicate type deduction for complex expressions - Binding contract forwarding for nested patterns - Member pointer validation in has<> patterns - Range boundary evaluation edge cases

Compilation Issues

Resolved: Template compilation problems: - Guard predicate instantiation failures - Binding pattern type deduction - Structural pattern member access validation - Predicate combinator type resolution