about summary refs log tree commit diff stats
path: root/js/baba-yaga/docs/03_pattern-matching.md
diff options
context:
space:
mode:
Diffstat (limited to 'js/baba-yaga/docs/03_pattern-matching.md')
-rw-r--r--js/baba-yaga/docs/03_pattern-matching.md133
1 files changed, 133 insertions, 0 deletions
diff --git a/js/baba-yaga/docs/03_pattern-matching.md b/js/baba-yaga/docs/03_pattern-matching.md
new file mode 100644
index 0000000..0bd663e
--- /dev/null
+++ b/js/baba-yaga/docs/03_pattern-matching.md
@@ -0,0 +1,133 @@
+# Pattern Matching
+
+The `when` expression matches a discriminant against patterns.
+
+## Literals and Wildcards
+```baba
+describe : x ->
+  when x is
+    0 then "Zero"
+    1 then "One"
+    _ then "Other";
+```
+
+## Multiple Discriminants
+```baba
+whereIs : x y ->
+  when x y is
+    0 0 then "Origin"
+    1 1 then "Diagonal"
+    _ _ then "Somewhere";
+```
+
+## Type Patterns
+```baba
+checkType : val ->
+  when val is
+    Int    then "Integer"
+    String then "String"
+    Bool   then "Boolean"
+    _      then "Other";
+```
+
+## Pattern Guards
+
+Use the `if` keyword to add conditional guards to patterns:
+
+```baba
+// Basic guards with range conditions
+categorizeNumber : n ->
+  when n is
+    x if (x > 0) then "positive"
+    x if (x < 0) then "negative"
+    0 then "zero";
+
+// Guards with complex conditions
+gradeStudent : score ->
+  when score is
+    s if (s >= 90) then "A"
+    s if (s >= 80 and s < 90) then "B"
+    s if (s >= 70 and s < 80) then "C"
+    s if (s >= 60 and s < 70) then "D"
+    s if (s < 60) then "F"
+    _ then "Invalid score";
+
+// Type guards
+processValue : value ->
+  when value is
+    Int if value > 100 then "large integer"
+    Int if value > 0 then "positive integer"
+    String if (length value) > 10 then "long string"
+    String if (length value) > 0 then "short string"
+    _ then "other";
+
+// Guards with wildcard patterns
+checkRange : x ->
+  when x is
+    _ if (x >= 1 and x <= 10) then "small"
+    _ if (x >= 11 and x <= 100) then "medium"
+    _ if (x > 100) then "large"
+    _ then "invalid";
+```
+
+Guards are evaluated after the underlying pattern matches. The guard expression has access to any variables bound by the pattern. This allows for sophisticated conditional matching without conflicting with the `..` string concatenation operator.
+
+## Typed discriminants
+
+When using typed functions that return `Result`, you can pattern match on variants and bind inner values.
+
+```baba
+divide : (x: Int, y: Int) -> Result ->
+  when y is
+    0 then Err "Division by zero"
+    _ then Ok (x / y);
+
+use : r ->
+  when r is
+    Ok val  then val
+    Err msg then msg;
+```
+
+## Result Patterns
+
+```baba
+divide : x y ->
+  when y is
+    0 then Err "Division by zero"
+    _ then Ok (x / y);
+
+use : r ->
+  when r is
+    Ok val  then val
+    Err msg then msg;
+```
+
+## Using `with` alongside `when`
+
+Use `with` to stage named locals used by discriminants and consequents.
+
+```baba
+classify : n ->
+  with (lo Int; hi Int; lo : 10; hi : 100;) ->
+    when n is
+      0 then "zero"
+      _ then when (n > hi) is
+               true then "large"
+               _    then when (n > lo) is
+                           true then "medium"
+                           _    then "small";
+```
+
+## List & Table Patterns
+
+```baba
+is123 : xs ->
+  when xs is
+    [1, 2, 3] then true
+    _         then false;
+
+hasA1B2 : t ->
+  when t is
+    { a: 1, b: 2 } then true
+    _              then false;
+```