Skip to content

Pattern Matching

Pattern matching provides a clean way to handle multiple conditions based on a value.

Basic Match Statement

The match statement compares a value against multiple cases:

let day = 3;

match day {
    case 1 => { print "Monday"; }
    case 2 => { print "Tuesday"; }
    case 3 => { print "Wednesday"; }
    case 4 => { print "Thursday"; }
    case 5 => { print "Friday"; }
    default => { print "Weekend"; }
}

Syntax

match value {
    case pattern1 => { /* code */ }
    case pattern2 => { /* code */ }
    default => { /* code */ }
}
  • Each case uses => followed by a block {}
  • The default case handles all unmatched values
  • Only one case executes (first match wins)

Matching Numbers

let score = 85;
let grade = "";

match score {
    case 90 => { grade = "A"; }
    case 80 => { grade = "B"; }
    case 70 => { grade = "C"; }
    case 60 => { grade = "D"; }
    default => { grade = "F"; }
}

print "Grade: #{grade}";

Matching Strings

let command = "start";

match command {
    case "start" => {
        print "Starting...";
    }
    case "stop" => {
        print "Stopping...";
    }
    case "pause" => {
        print "Pausing...";
    }
    case "resume" => {
        print "Resuming...";
    }
    default => {
        print "Unknown command";
    }
}

Matching Booleans

let is_admin = true;

match is_admin {
    case true => {
        print "Admin access granted";
    }
    case false => {
        print "Regular user";
    }
}

Using Match in Functions

fn get_day_name(day) {
    let name = "";

    match day {
        case 1 => { name = "Monday"; }
        case 2 => { name = "Tuesday"; }
        case 3 => { name = "Wednesday"; }
        case 4 => { name = "Thursday"; }
        case 5 => { name = "Friday"; }
        case 6 => { name = "Saturday"; }
        case 7 => { name = "Sunday"; }
        default => { name = "Invalid"; }
    }

    return name;
}

print get_day_name(3);  // Wednesday

Status Codes

fn get_http_status_message(code) {
    let message = "";

    match code {
        case 200 => { message = "OK"; }
        case 201 => { message = "Created"; }
        case 404 => { message = "Not Found"; }
        case 500 => { message = "Internal Server Error"; }
        case 403 => { message = "Forbidden"; }
        default => { message = "Unknown Status"; }
    }

    return message;
}

print get_http_status_message(404);  // Not Found

Calculator Example

fn calculate(operation, a, b) {
    let result = 0;

    match operation {
        case "add" => {
            result = a + b;
        }
        case "subtract" => {
            result = a - b;
        }
        case "multiply" => {
            result = a * b;
        }
        case "divide" => {
            if b != 0 {
                result = a / b;
            } else {
                print "Error: Division by zero";
            }
        }
        default => {
            print "Unknown operation";
        }
    }

    return result;
}

print calculate("add", 10, 5);       // 15
print calculate("multiply", 4, 7);   // 28

Game State Machine

let game_state = "playing";

match game_state {
    case "menu" => {
        print "Showing menu";
    }
    case "playing" => {
        print "Game in progress";
    }
    case "paused" => {
        print "Game paused";
    }
    case "game_over" => {
        print "Game over - Final score shown";
    }
    default => {
        print "Unknown state";
    }
}

Color Codes

let color = "red";

match color {
    case "red" => {
        print "RGB: 255, 0, 0";
    }
    case "green" => {
        print "RGB: 0, 255, 0";
    }
    case "blue" => {
        print "RGB: 0, 0, 255";
    }
    case "white" => {
        print "RGB: 255, 255, 255";
    }
    case "black" => {
        print "RGB: 0, 0, 0";
    }
    default => {
        print "Custom color";
    }
}

Permissions System

struct User {
    name,
    role
}

let user = User { name: "Alice", role: "admin" };

match user.role {
    case "admin" => {
        print "Full access granted";
    }
    case "moderator" => {
        print "Moderate access granted";
    }
    case "user" => {
        print "Basic access granted";
    }
    case "guest" => {
        print "Read-only access";
    }
    default => {
        print "Access denied";
    }
}
fn handle_menu_choice(choice) {
    match choice {
        case 1 => {
            print "Creating new file...";
        }
        case 2 => {
            print "Opening file...";
        }
        case 3 => {
            print "Saving file...";
        }
        case 4 => {
            print "Exiting...";
        }
        default => {
            print "Invalid choice";
        }
    }
}

let selection = 2;
handle_menu_choice(selection);

Match vs If-Else

Using If-Else

let status = "active";

if status == "active" {
    print "System running";
} else {
    if status == "inactive" {
        print "System stopped";
    } else {
        if status == "error" {
            print "System error";
        } else {
            print "Unknown status";
        }
    }
}

Using Match (Cleaner)

let status = "active";

match status {
    case "active" => { print "System running"; }
    case "inactive" => { print "System stopped"; }
    case "error" => { print "System error"; }
    default => { print "Unknown status"; }
}

Traffic Light System

fn traffic_light_action(color) {
    match color {
        case "red" => {
            print "STOP";
            print "Wait for green light";
        }
        case "yellow" => {
            print "CAUTION";
            print "Prepare to stop";
        }
        case "green" => {
            print "GO";
            print "Proceed safely";
        }
        default => {
            print "Light malfunction";
        }
    }
}

traffic_light_action("yellow");

Best Practices

1. Always Include Default

// Good - handles unexpected values
match value {
    case 1 => { /* ... */ }
    case 2 => { /* ... */ }
    default => { print "Unexpected value"; }
}

2. Use for Fixed Set of Values

// Good - fixed set of directions
match direction {
    case "north" => { /* ... */ }
    case "south" => { /* ... */ }
    case "east" => { /* ... */ }
    case "west" => { /* ... */ }
    default => { /* ... */ }
}

3. Keep Cases Simple

// Good - simple, focused cases
match type {
    case "user" => { handle_user(); }
    case "admin" => { handle_admin(); }
    default => { handle_unknown(); }
}

// Avoid - too much logic in case
match type {
    case "user" => {
        // 50 lines of code here...
    }
}

When to Use Match

Use Match When: - Comparing one value against many possibilities - Have a fixed set of options - Want cleaner code than nested if-else

Use If-Else When: - Need range checking (x > 5 && x < 10) - Have complex boolean conditions - Need to check multiple different variables

Limitations

Match in CacaoLang: - Only matches exact values (no ranges) - No fall-through (unlike switch in C) - One value at a time (can't match multiple values in one case)

For complex patterns, use if-else:

// Use if-else for ranges
if score >= 90 {
    grade = "A";
} else if score >= 80 {
    grade = "B";
}

Next Steps