Pattern Matching

Use exhaustive matching over enums so every legal state has defined behavior.

1

Core concepts

exhaustive match, enum patterns, struct wrapping an enum

2

How the learner should approach this project

Do not paste the complete program immediately. Create the file, type the first step, run vpp check, and then run the program when a complete entry point exists. Read the explanation before looking at the snippet. After each step, predict what the new code should do. This turns the page into a lesson rather than a code dump.

3

Step 1: Define Day

The Day enum lists every day. Because the compiler knows all seven variants, a match can be checked for completeness.

After typing the snippet, identify the new names introduced by the step. Ask what each name represents, what type the compiler should infer or check, and what value should exist after the code runs.

main.vpp
enum Day {
    Mon
    Tue
    Wed
    Thu
    Fri
    Sat
    Sun
}
4

Step 2: Wrap Day in a struct

CalendarDay gives the example a named field. This is useful when a larger model eventually contains more information about a date.

Before moving forward, explain how this step connects to the previous one. In particular, identify which values cross a function boundary, which values change, and which values are guaranteed by the type system.

main.vpp
struct CalendarDay {
    day: Day
}
5

Step 3: Write an exhaustive weekend check

The function returns true for Sat and Sun and false for every weekday. There is no default branch because the compiler can verify that all seven variants are covered explicitly.

Before moving forward, explain how this step connects to the previous one. In particular, identify which values cross a function boundary, which values change, and which values are guaranteed by the type system.

main.vpp
fn is_weekend(entry: CalendarDay) -> bool {
    match entry.day {
        Sat => {
            return true
        }
        Sun => {
            return true
        }
        Mon => {
            return false
        }
        Tue => {
            return false
        }
        Wed => {
            return false
        }
        Thu => {
            return false
        }
        Fri => {
            return false
        }
    }
}
6

Step 4: Test two cases

The main function constructs one weekend value and one weekday value. Calling the same function with both demonstrates that the enum controls behavior without unsafe integer codes.

Before moving forward, explain how this step connects to the previous one. In particular, identify which values cross a function boundary, which values change, and which values are guaranteed by the type system.

main.vpp
fn main() -> int {
    let weekend = CalendarDay { day: Sat }
    let weekday = CalendarDay { day: Wed }
    print(is_weekend(weekend))
    print(is_weekend(weekday))
    return 0
}
7

Complete source

main.vpp
enum Day {
    Mon
    Tue
    Wed
    Thu
    Fri
    Sat
    Sun
}
struct CalendarDay {
    day: Day
}
fn is_weekend(entry: CalendarDay) -> bool {
    match entry.day {
        Sat => {
            return true
        }
        Sun => {
            return true
        }
        Mon => {
            return false
        }
        Tue => {
            return false
        }
        Wed => {
            return false
        }
        Thu => {
            return false
        }
        Fri => {
            return false
        }
    }
}
fn main() -> int {
    let weekend = CalendarDay { day: Sat }
    let weekday = CalendarDay { day: Wed }
    print(is_weekend(weekend))
    print(is_weekend(weekday))
    return 0
}
8

Expected behavior

The complete program should produce the following output when run with the command shown below. Exact formatting should follow the current V++ runtime.

true
false
9

Run the project

terminal
vpp run projects/09-match/main.vpp
10

What the learner should understand after this project

Exhaustiveness is a compile time safety property. Adding a new enum variant creates a deliberate reminder to update affected match expressions.

11

Common mistakes to teach

  1. Removing a match arm and ignoring the exhaustiveness error
  2. Confusing the enum value with the struct that contains it
  3. Returning the wrong boolean for a variant
12

Practice extension

Intentionally remove one match arm and run vpp check. Study the compiler error, then restore the missing case.

A strong learner should be able to explain the program without looking at the code, rebuild the core idea from memory, and make the practice change without copying a solution.

13

Full program

main.vpp
enum Day {
    Mon
    Tue
    Wed
    Thu
    Fri
    Sat
    Sun
}
struct CalendarDay {
    day: Day
}
fn is_weekend(entry: CalendarDay) -> bool {
    match entry.day {
        Sat => {
            return true
        }
        Sun => {
            return true
        }
        Mon => {
            return false
        }
        Tue => {
            return false
        }
        Wed => {
            return false
        }
        Thu => {
            return false
        }
        Fri => {
            return false
        }
    }
}
fn main() -> int {
    let weekend = CalendarDay { day: Sat }
    let weekday = CalendarDay { day: Wed }
    print(is_weekend(weekend))
    print(is_weekend(weekday))
    return 0
}
vpp
$ ready. Click Test program.