diff options
Diffstat (limited to 'js/scripting-lang/tutorials/05_Pattern_Matching.md')
-rw-r--r-- | js/scripting-lang/tutorials/05_Pattern_Matching.md | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/js/scripting-lang/tutorials/05_Pattern_Matching.md b/js/scripting-lang/tutorials/05_Pattern_Matching.md new file mode 100644 index 0000000..c6097c3 --- /dev/null +++ b/js/scripting-lang/tutorials/05_Pattern_Matching.md @@ -0,0 +1,247 @@ +# `when` Expressions (Pattern Matching) + +## What are `when` Expressions? + +This is kinda where the whole idea for Baba Yaga started. Pattern matching is an approach to flow control. We do this in Baba Yaga using the `when` expression. It provides pattern matching functionality, allowing you to match values against patterns and execute different code based on the match. + +```plaintext +/* Pattern matching with when expressions */ +result : when x is + 0 then "zero" + 1 then "one" + _ then "other"; +``` + +Baba Yaga's pattern matching syntax has a lot of insporations, but especially `cond` patterns, Gleam's pattern matching, and Roc's, too. + +## Basic Examples + +```plaintext +/* Simple pattern matching */ +x : 5; +result : when x is + 0 then "zero" + 1 then "one" + 2 then "two" + _ then "other"; +/* Result: "other" */ + +/* Pattern matching with numbers */ +grade : 85; +letter_grade : when grade is + 90 then "A" + 80 then "B" + 70 then "C" + 60 then "D" + _ then "F"; +/* Result: "B" */ +``` + +## Pattern Types + +### Literal Patterns +```plaintext +/* Match exact values */ +result : when value is + true then "yes" + false then "no" + _ then "maybe"; +``` + +### Wildcard Pattern +```plaintext +/* _ matches anything */ +result : when x is + 0 then "zero" + _ then "not zero"; +``` + +### Function Reference Patterns +```plaintext +/* Match function references using @ operator */ +double : x -> x * 2; +square : x -> x * x; + +which : x -> when x is + @double then "doubling function" + @square then "squaring function" + _ then "other function"; + +test1 : which double; +test2 : which square; +``` + +As is called out elsewhere, too, the `@` operator is required when matching function references in patterns. This distinguishes between calling a function and matching against the function itself. + +### Boolean Patterns +```plaintext +/* Match boolean values */ +result : when condition is + true then "condition is true" + false then "condition is false"; +``` + +## Complex Examples + +```plaintext +/* Grade classification with ranges */ +score : 85; +grade : when score is + when score >= 90 then "A" + when score >= 80 then "B" + when score >= 70 then "C" + when score >= 60 then "D" + _ then "F"; +/* Result: "B" */ + +/* Multiple conditions */ +x : 5; +y : 10; +result : when x is + when x = y then "equal" + when x > y then "x is greater" + when x < y then "x is less" + _ then "impossible"; +/* Result: "x is less" */ +``` + +## Advanced Pattern Matching + +You can match multiple values with complex expressions: + +```plaintext +/* FizzBuzz implementation using multi-value patterns */ +fizzbuzz : n -> + when (n % 3) (n % 5) is + 0 0 then "FizzBuzz" + 0 _ then "Fizz" + _ 0 then "Buzz" + _ _ then n; + +/* Test the FizzBuzz function */ +result1 : fizzbuzz 15; /* "FizzBuzz" */ +result2 : fizzbuzz 3; /* "Fizz" */ +result3 : fizzbuzz 5; /* "Buzz" */ +result4 : fizzbuzz 7; /* 7 */ +``` + +You can access table properties directly in patterns: + +```plaintext +/* User role checking */ +user : {role: "admin", level: 5}; + +access_level : when user.role is + "admin" then "full access" + "user" then "limited access" + _ then "no access"; +/* Result: "full access" */ +``` + +You can use function calls in patterns. Be warned, though -- they require parentheses to help disambiguate them from other references, though. + +```plaintext +/* Even/odd classification */ +is_even : n -> n % 2 = 0; + +classify : n -> + when (is_even n) is + true then "even number" + false then "odd number"; + +/* Test the classification */ +result1 : classify 4; /* "even number" */ +result2 : classify 7; /* "odd number" */ +``` + +Function calls in patterns must be wrapped in parentheses! + +This'll work: +```plaintext +when (is_even n) is true then "even" +when (complex_func x y) is result then "matched" +``` + +This won't work: +```plaintext +when is_even n is true then "even" /* Ambiguous parsing */ +``` + +You can nest `when` expressions for complex logic: + +```plaintext +/* Nested pattern matching */ +x : 5; +y : 10; +result : when x is + 0 then when y is + 0 then "both zero" + _ then "x is zero" + 1 then when y is + 1 then "both one" + _ then "x is one" + _ then when y is + 0 then "y is zero" + 1 then "y is one" + _ then "neither special"; +/* Result: "neither special" */ +``` + +## Using `when` with Functions + +```plaintext +/* Function that uses pattern matching */ +classify_number : x -> when x is + 0 then "zero" + (x % 2 = 0) then "even" + (x % 2 = 1) then "odd" + _ then "unknown"; + +/* Use the function */ +result1 : classify_number 0; /* "zero" */ +result2 : classify_number 4; /* "even" */ +result3 : classify_number 7; /* "odd" */ +``` + +## Common Patterns + +```plaintext +/* Value classification */ +classify_age : age -> when age is + (age < 13) then "child" + (age < 20) then "teenager" + (age < 65) then "adult" + _ then "senior"; + +/* Error handling */ +safe_divide : x y -> when y is + 0 then "error: division by zero" + _ then x / y; + +/* Status mapping */ +status_code : 404; +status_message : x -> + when x is + 200 then "OK" + 404 then "Not Found" + 500 then "Internal Server Error" + _ then "Unknown Error"; +``` + +## When to Use `when` pattern matching + +**Use `when` expressions when:** +- You need to match values against multiple patterns +- You want to replace complex if/else chains +- You're working with enumerated values +- You need to handle different cases based on value types +- You want to make conditional logic more readable +- **You need to match multiple values simultaneously** (multi-value patterns) +- **You want to access table properties in patterns** (table access) +- **You need to use function results in patterns** (function calls with parentheses) +- **You're implementing complex validation logic** (multi-field validation) +- **You need to match function references** (using `@` operator) + +**Don't use `when` expressions when:** +- You only have a simple true/false condition (use logical operators) +- You're working with complex nested conditions (consider breaking into functions) \ No newline at end of file |