about summary refs log tree commit diff stats
path: root/js/scripting-lang/tutorials/05_Pattern_Matching.md
diff options
context:
space:
mode:
Diffstat (limited to 'js/scripting-lang/tutorials/05_Pattern_Matching.md')
-rw-r--r--js/scripting-lang/tutorials/05_Pattern_Matching.md247
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