about summary refs log tree commit diff stats
path: root/js/baba-yaga/scratch/baba
diff options
context:
space:
mode:
Diffstat (limited to 'js/baba-yaga/scratch/baba')
-rw-r--r--js/baba-yaga/scratch/baba/compatibility-test.baba30
-rw-r--r--js/baba-yaga/scratch/baba/conway-simple.baba116
-rw-r--r--js/baba-yaga/scratch/baba/conway-test.baba16
-rw-r--r--js/baba-yaga/scratch/baba/conway-working.baba120
-rw-r--r--js/baba-yaga/scratch/baba/conway.baba126
-rw-r--r--js/baba-yaga/scratch/baba/crash-course-code.baba240
-rw-r--r--js/baba-yaga/scratch/baba/example.baba269
-rw-r--r--js/baba-yaga/scratch/baba/functional-features-demo.baba128
-rw-r--r--js/baba-yaga/scratch/baba/game-of-life.baba76
-rw-r--r--js/baba-yaga/scratch/baba/indentation_test.baba20
-rw-r--r--js/baba-yaga/scratch/baba/life-demo-alt.baba91
-rw-r--r--js/baba-yaga/scratch/baba/life-demo.baba91
-rw-r--r--js/baba-yaga/scratch/baba/life-example.baba181
-rw-r--r--js/baba-yaga/scratch/baba/life-final.baba59
-rw-r--r--js/baba-yaga/scratch/baba/life-simple.baba51
-rw-r--r--js/baba-yaga/scratch/baba/life.baba90
-rw-r--r--js/baba-yaga/scratch/baba/nested_when_test.baba30
-rw-r--r--js/baba-yaga/scratch/baba/nested_when_working.baba12
-rw-r--r--js/baba-yaga/scratch/baba/simple.baba8
-rw-r--r--js/baba-yaga/scratch/baba/simple_nested_when.baba8
-rw-r--r--js/baba-yaga/scratch/baba/test_comprehensive_features.baba87
-rw-r--r--js/baba-yaga/scratch/baba/test_error_docs.baba40
-rw-r--r--js/baba-yaga/scratch/baba/test_error_handling.baba47
-rw-r--r--js/baba-yaga/scratch/baba/test_functional_enhancements.baba132
-rw-r--r--js/baba-yaga/scratch/baba/test_grid_display.baba20
-rw-r--r--js/baba-yaga/scratch/baba/test_io_print.baba34
-rw-r--r--js/baba-yaga/scratch/baba/test_logical_and.baba7
-rw-r--r--js/baba-yaga/scratch/baba/test_pattern_guards.baba57
-rw-r--r--js/baba-yaga/scratch/baba/test_then_alignment.baba18
-rw-r--r--js/baba-yaga/scratch/baba/test_utilities.baba106
-rw-r--r--js/baba-yaga/scratch/baba/then_alignment_demo.baba27
-rw-r--r--js/baba-yaga/scratch/baba/with.baba217
32 files changed, 2554 insertions, 0 deletions
diff --git a/js/baba-yaga/scratch/baba/compatibility-test.baba b/js/baba-yaga/scratch/baba/compatibility-test.baba
new file mode 100644
index 0000000..4b13231
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/compatibility-test.baba
@@ -0,0 +1,30 @@
+// Compatibility test between optimized and legacy engines
+
+// Test variable names with underscores and numbers
+var_with_underscore : 42;
+var123 : 123;
+test_var_2 : "hello";
+
+// Test complex expressions
+result1 : var_with_underscore + var123;
+result2 : when (result1 > 100) is true then "big" _ then "small";
+
+// Test function definitions
+testFunc : a b -> a * b + var123;
+funcResult : testFunc 5 6;
+
+// Test nested when expressions
+nested : when (funcResult > 150) is 
+  true then when (var123 = 123) is true then "both true" _ then "first true"
+  _ then "first false";
+
+// Output results
+io.out "Compatibility Test Results:";
+io.out "var_with_underscore:"; io.out var_with_underscore;
+io.out "var123:"; io.out var123;  
+io.out "test_var_2:"; io.out test_var_2;
+io.out "result1:"; io.out result1;
+io.out "result2:"; io.out result2;
+io.out "funcResult:"; io.out funcResult;
+io.out "nested:"; io.out nested;
+io.out "Test complete!";
diff --git a/js/baba-yaga/scratch/baba/conway-simple.baba b/js/baba-yaga/scratch/baba/conway-simple.baba
new file mode 100644
index 0000000..1054106
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/conway-simple.baba
@@ -0,0 +1,116 @@
+// Conway's Game of Life - Simple Working Version
+
+// Get element at index from list (safe)
+at : xs i ->
+  when (i >= 0 and i < length xs) is
+    true then slice xs i (i + 1).0
+    _ then 0;
+
+// Get 2D element from grid (safe)
+get2d : grid row col ->
+  when (row >= 0 and row < length grid and col >= 0) is
+    true then 
+      with (rowData : at grid row) ->
+        when (col < length rowData) is
+          true then at rowData col
+          _ then 0
+    _ then 0;
+
+// Count living neighbors around position (row, col)
+countNeighbors : grid row col ->
+  with (
+    n1 : get2d grid (row - 1) (col - 1);
+    n2 : get2d grid (row - 1) col;
+    n3 : get2d grid (row - 1) (col + 1);
+    n4 : get2d grid row (col - 1);
+    n5 : get2d grid row (col + 1);
+    n6 : get2d grid (row + 1) (col - 1);
+    n7 : get2d grid (row + 1) col;
+    n8 : get2d grid (row + 1) (col + 1);
+  ) -> n1 + n2 + n3 + n4 + n5 + n6 + n7 + n8;
+
+// Apply Game of Life rules to a single cell
+nextCellState : grid row col ->
+  with (
+    current : get2d grid row col;
+    neighbors : countNeighbors grid row col;
+  ) ->
+    when current is
+      1 then 
+        when (neighbors = 2 or neighbors = 3) is
+          true then 1
+          _ then 0
+      _ then
+        when (neighbors = 3) is
+          true then 1
+          _ then 0;
+
+// Generate next generation of the entire grid
+nextGeneration : grid ->
+  with (
+    height : length grid;
+    width : length (at grid 0);
+    // Create new grid row by row
+    newRow : rowIdx -> 
+      with (
+        newCol : colIdx -> nextCellState grid rowIdx colIdx;
+        cols : [0, 1, 2, 3, 4]; // Assuming 5x5 for now
+      ) -> map newCol cols;
+    rows : [0, 1, 2, 3, 4]; // Assuming 5x5 for now
+  ) -> map newRow rows;
+
+// Print a single row
+printRow : row ->
+  with (
+    cellToChar : cell -> when cell is 1 then "#" _ then ".";
+    chars : map cellToChar row;
+  ) -> io.out chars;
+
+// Print entire grid with title
+printGrid : grid title ->
+  with (
+    _ : io.out "";
+    _ : io.out title;
+    _ : io.out "-----";
+    _ : map printRow grid;
+  ) -> 0; // Return dummy value
+
+// Test patterns
+
+// Glider pattern (moves diagonally)
+glider : [
+  [0, 1, 0, 0, 0],
+  [0, 0, 1, 0, 0], 
+  [1, 1, 1, 0, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+
+// Blinker pattern (oscillates)
+blinker : [
+  [0, 0, 0, 0, 0],
+  [0, 1, 1, 1, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+
+// Run simulations
+io.out "Conway's Game of Life";
+io.out "====================";
+
+// Show initial glider
+dummy1 : printGrid glider "Glider - Generation 0";
+g1 : nextGeneration glider;
+dummy2 : printGrid g1 "Glider - Generation 1";
+g2 : nextGeneration g1;
+dummy3 : printGrid g2 "Glider - Generation 2";
+
+// Show blinker oscillation
+dummy4 : printGrid blinker "Blinker - Generation 0";
+b1 : nextGeneration blinker;
+dummy5 : printGrid b1 "Blinker - Generation 1";
+b2 : nextGeneration b1;
+dummy6 : printGrid b2 "Blinker - Generation 2";
+
+io.out "Done!";
diff --git a/js/baba-yaga/scratch/baba/conway-test.baba b/js/baba-yaga/scratch/baba/conway-test.baba
new file mode 100644
index 0000000..ef8be99
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/conway-test.baba
@@ -0,0 +1,16 @@
+// Simple Game of Life test
+
+// Safe array access
+at : xs i ->
+  when (i >= 0 and i < length xs) is
+    true then slice xs i (i + 1).0
+    _ then 0;
+
+// Test pattern
+pattern : [[0, 1, 0], [0, 0, 1], [1, 1, 1]];
+
+io.out "Testing:";
+io.out pattern;
+io.out "Cell at (1,1):";
+io.out (at (at pattern 1) 1);
+io.out "Done!";
diff --git a/js/baba-yaga/scratch/baba/conway-working.baba b/js/baba-yaga/scratch/baba/conway-working.baba
new file mode 100644
index 0000000..e010e96
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/conway-working.baba
@@ -0,0 +1,120 @@
+// Conway's Game of Life - Minimal Working Version
+
+// Safe array access
+at : xs i ->
+  when (i >= 0 and i < length xs) is
+    true then slice xs i (i + 1).0
+    _ then 0;
+
+// Safe 2D grid access  
+get2d : grid row col ->
+  when (row >= 0 and row < length grid) is
+    true then at (at grid row) col
+    _ then 0;
+
+// Count living neighbors
+countNeighbors : grid row col ->
+  (get2d grid (row - 1) (col - 1)) +
+  (get2d grid (row - 1) col) +
+  (get2d grid (row - 1) (col + 1)) +
+  (get2d grid row (col - 1)) +
+  (get2d grid row (col + 1)) +
+  (get2d grid (row + 1) (col - 1)) +
+  (get2d grid (row + 1) col) +
+  (get2d grid (row + 1) (col + 1));
+
+// Apply Game of Life rules
+nextCell : grid row col ->
+  with (
+    current : get2d grid row col;
+    neighbors : countNeighbors grid row col;
+  ) ->
+    when current is
+      1 then when (neighbors = 2 or neighbors = 3) is true then 1 _ then 0
+      _ then when (neighbors = 3) is true then 1 _ then 0;
+
+// Generate next generation (hardcoded for 5x5)
+nextGeneration : grid -> [
+  [
+    nextCell grid 0 0,
+    nextCell grid 0 1, 
+    nextCell grid 0 2,
+    nextCell grid 0 3,
+    nextCell grid 0 4
+  ],
+  [
+    nextCell grid 1 0,
+    nextCell grid 1 1,
+    nextCell grid 1 2, 
+    nextCell grid 1 3,
+    nextCell grid 1 4
+  ],
+  [
+    nextCell grid 2 0,
+    nextCell grid 2 1,
+    nextCell grid 2 2,
+    nextCell grid 2 3, 
+    nextCell grid 2 4
+  ],
+  [
+    nextCell grid 3 0,
+    nextCell grid 3 1,
+    nextCell grid 3 2,
+    nextCell grid 3 3,
+    nextCell grid 3 4
+  ],
+  [
+    nextCell grid 4 0,
+    nextCell grid 4 1,
+    nextCell grid 4 2,
+    nextCell grid 4 3,
+    nextCell grid 4 4
+  ]
+];
+
+// Test patterns
+glider : [
+  [0, 1, 0, 0, 0],
+  [0, 0, 1, 0, 0],
+  [1, 1, 1, 0, 0], 
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+
+blinker : [
+  [0, 0, 0, 0, 0],
+  [0, 1, 1, 1, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+
+// Run simulation
+io.out "Conway's Game of Life";
+io.out "====================";
+
+io.out "Glider - Generation 0:";
+io.out glider;
+
+g1 : nextGeneration glider;
+io.out "Glider - Generation 1:";
+io.out g1;
+
+g2 : nextGeneration g1;
+io.out "Glider - Generation 2:";
+io.out g2;
+
+io.out "";
+io.out "Blinker - Generation 0:";
+io.out blinker;
+
+b1 : nextGeneration blinker;
+io.out "Blinker - Generation 1:";
+io.out b1;
+
+b2 : nextGeneration b1;
+io.out "Blinker - Generation 2:";
+io.out b2;
+
+io.out "";
+io.out "Simulation complete!";
diff --git a/js/baba-yaga/scratch/baba/conway.baba b/js/baba-yaga/scratch/baba/conway.baba
new file mode 100644
index 0000000..a8811a7
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/conway.baba
@@ -0,0 +1,126 @@
+// Conway's Game of Life in Baba Yaga
+// Clean, working implementation
+
+// Get element at index from list (with bounds checking)
+at : xs i ->
+  when (i >= 0 and i < length xs) is
+    true then slice xs i (i + 1).0
+    _ then 0;
+
+// Get 2D element from grid
+get2d : grid row col ->
+  when (row >= 0 and row < length grid) is
+    true then at (at grid row) col
+    _ then 0;
+
+// Create range of integers [start, end)
+range : start end ->
+  when (start >= end) is
+    true then []
+    _ then prepend start (range (start + 1) end);
+
+// Sum a list of numbers
+sum : xs -> reduce (acc x -> acc + x) 0 xs;
+
+// Count living neighbors around position (row, col)
+countNeighbors : grid row col ->
+  with (
+    // Get all 8 neighbor positions
+    neighbors : [
+      get2d grid (row - 1) (col - 1),
+      get2d grid (row - 1) col,
+      get2d grid (row - 1) (col + 1),
+      get2d grid row (col - 1),
+      get2d grid row (col + 1),
+      get2d grid (row + 1) (col - 1),
+      get2d grid (row + 1) col,
+      get2d grid (row + 1) (col + 1)
+    ];
+  ) -> sum neighbors;
+
+// Apply Game of Life rules to a single cell
+nextCellState : grid row col ->
+  with (
+    current : get2d grid row col;
+    neighbors : countNeighbors grid row col;
+    isAlive : current = 1;
+  ) ->
+    when isAlive is
+      true then 
+        when (neighbors = 2 or neighbors = 3) is
+          true then 1
+          _ then 0
+      _ then
+        when (neighbors = 3) is
+          true then 1
+          _ then 0;
+
+// Generate next row for the grid
+nextRow : grid rowIndex width ->
+  map (col -> nextCellState grid rowIndex col) (range 0 width);
+
+// Generate next generation of the entire grid
+nextGeneration : grid ->
+  with (
+    height : length grid;
+    width : length (at grid 0);
+  ) ->
+    map (row -> nextRow grid row width) (range 0 height);
+
+// Pretty print a grid
+printGrid : grid title ->
+  with (
+    printRow : row -> io.out (map (cell -> when cell is 1 then "#" _ then ".") row);
+  ) -> with (
+    _ : io.out "";
+    _ : io.out title;
+    _ : io.out (map (_ -> "-") (range 0 20));
+    _ : map printRow grid;
+    _ : io.out "";
+  ) -> grid;
+
+// Test patterns
+
+// Glider pattern (moves diagonally)
+glider : [
+  [0, 1, 0, 0, 0],
+  [0, 0, 1, 0, 0], 
+  [1, 1, 1, 0, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+
+// Blinker pattern (oscillates)
+blinker : [
+  [0, 0, 0],
+  [1, 1, 1],
+  [0, 0, 0]
+];
+
+// Block pattern (still life)
+block : [
+  [1, 1],
+  [1, 1]
+];
+
+// Run simulations
+io.out "Conway's Game of Life in Baba Yaga";
+io.out "====================================";
+
+// Glider evolution
+g0 : printGrid glider "Glider - Generation 0";
+g1 : printGrid (nextGeneration g0) "Glider - Generation 1";
+g2 : printGrid (nextGeneration g1) "Glider - Generation 2";
+g3 : printGrid (nextGeneration g2) "Glider - Generation 3";
+g4 : printGrid (nextGeneration g3) "Glider - Generation 4";
+
+// Blinker oscillation
+b0 : printGrid blinker "Blinker - Generation 0";
+b1 : printGrid (nextGeneration b0) "Blinker - Generation 1";
+b2 : printGrid (nextGeneration b1) "Blinker - Generation 2";
+
+// Block (should stay the same)
+bl0 : printGrid block "Block - Generation 0";
+bl1 : printGrid (nextGeneration bl0) "Block - Generation 1";
+
+io.out "Simulation complete!";
diff --git a/js/baba-yaga/scratch/baba/crash-course-code.baba b/js/baba-yaga/scratch/baba/crash-course-code.baba
new file mode 100644
index 0000000..bae2810
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/crash-course-code.baba
@@ -0,0 +1,240 @@
+// Baba Yaga in Y Minutes
+
+// Test 1: Basic with examples
+testBasicWith : x y ->
+  with (inc : x + 1; prod : inc * y;) -> inc + prod;
+
+testTypedWith : x y ->
+  with (nx Int; ny Int; nx : x + 1; ny : y + 1;) -> nx + ny;
+
+// Test 2: with rec examples
+testEvenOdd : z ->
+  with rec (
+    isEven : n -> when n is 0 then true _ then isOdd (n - 1);
+    isOdd : n -> when n is 0 then false _ then isEven (n - 1);
+  ) -> {even: isEven z, odd: isOdd z};
+
+// Test 3: Computed intermediate values
+testQuadraticRoots : a b c ->
+  with (
+    discriminant : b * b - 4 * a * c;
+    sqrtDisc : math.sqrt discriminant;
+    denominator : 2 * a;
+  ) ->
+    {
+      r1: (-b + sqrtDisc) / denominator,
+      r2: (-b - sqrtDisc) / denominator
+    };
+
+// Test 4: Complex calculations with named steps
+testCalculateTax : income deductions ->
+  with (
+    taxableIncome : income - deductions;
+    taxRate : when (taxableIncome <= 50000) is
+      true then 0.15
+      _ then when (taxableIncome <= 100000) is
+        true then 0.25
+        _ then 0.35;
+    baseTax : taxableIncome * taxRate;
+    finalTax : when (baseTax < 1000) is true then 1000 _ then baseTax;
+  ) ->
+    finalTax;
+
+// Test 5: Data transformation pipelines
+testProcessUserData : user ->
+  with (
+    normalizedName : str.upper (str.trim user.name);
+    ageGroup : when (user.age < 18) is
+      true then "minor"
+         _ then when (user.age < 65) is
+                true then "adult"
+                   _ then "senior";
+     status : when user.active is
+        true then "active"
+           _ then "inactive";
+  ) ->
+    {
+      id: user.id,
+      displayName: normalizedName,
+      category: ageGroup,
+      status: status
+    };
+
+// Test 6: Error handling with multiple validations
+testValidateOrder : order ->
+  with (
+    hasItems : (length order.items) > 0;
+    hasValidTotal : order.total > 0;
+    allValid : hasItems and hasValidTotal;
+  ) ->
+    when allValid is
+      true then Ok order
+      _    then Err "Order validation failed";
+
+// Test 7: Complex pattern matching with computed values
+testClassifyTriangle : a b c ->
+  with (
+    sorted : [math.min a b, math.max a b, math.max (math.max a b) c];
+    side1 : sorted.0;
+    side2 : sorted.1;
+    side3 : sorted.2;
+    isValid : ((side1 + side2) > side3);
+    isEquilateral : ((a = b) and (b = c));
+    isIsosceles : ((a = b) or (b = c) or (a = c));
+    isRight : (math.abs ((side1 * side1 + side2 * side2) - (side3 * side3))) < 0.001;
+  ) ->
+    when isValid is
+      false then "Invalid triangle"
+      _     then when isEquilateral is
+                 true then "Equilateral"
+                    _ then when isIsosceles is
+                           true then when isRight is
+                                     true then "Right isosceles"
+                                        _ then "Isosceles"
+                                        _ then when isRight is
+                                               true then "Right scalene"
+                                                  _ then "Scalene";
+
+// Test 8: Tree operations with with rec
+testTreeOperations : tree ->
+  with rec (
+    // Count total nodes
+    countNodes : t ->
+      when ((length (keys t)) = 0) is
+        true then 0
+        _ then 1 + (countNodes t.left) + (countNodes t.right);
+    
+    // Calculate tree height
+    treeHeight : t ->
+      when ((length (keys t)) = 0) is
+        true then 0
+        _ then 1 + (math.max (treeHeight t.left) (treeHeight t.right));
+    
+    // Check if tree is balanced
+    isBalanced : t ->
+      when ((length (keys t)) = 0) is
+        true then true
+        _ then 
+          (((math.abs ((treeHeight t.left) - (treeHeight t.right))) <= 1) and
+          (isBalanced t.left) and
+          (isBalanced t.right));
+  ) ->
+    {
+      nodeCount: countNodes tree,
+      height: treeHeight tree,
+      balanced: isBalanced tree
+    };
+
+// Test 9: State machine with recursive state transitions
+testTrafficLight : initialState ->
+  with rec (
+    // State transition function
+    nextState : current ->
+      when current is
+        "red" then "green"
+        "green" then "yellow"
+        _ then "red";
+    
+    // Count transitions until back to start
+    countCycles : start current count ->
+      when (current = start) is
+        true then count
+        _ then countCycles start (nextState current) (count + 1);
+    
+    // Get state after N transitions
+    stateAfter : current n ->
+      when n is
+        0 then current
+        _ then stateAfter (nextState current) (n - 1);
+  ) ->
+    {
+      cycles: countCycles initialState initialState 0,
+      after10: stateAfter initialState 10,
+      next: nextState initialState
+    };
+
+// Test 10: Combinatorial functions with shared helpers
+testCombinatorics : n r ->
+  with rec (
+    // Factorial function
+    factorial : k ->
+      when k is
+        0 then 1
+        1 then 1
+        _ then k * (factorial (k - 1));
+    
+    // Permutation: P(n,r) = n! / (n-r)!
+    permutation : n r ->
+      (factorial n) / (factorial (n - r));
+    
+    // Combination: C(n,r) = n! / (r! * (n-r)!)
+    combination : n r ->
+      (factorial n) / ((factorial r) * (factorial (n - r)));
+  ) ->
+    {
+      n: n,
+      r: r,
+      permutations: permutation n r,
+      combinations: combination n r
+    };
+
+// Test 11: Best practices examples
+testProcessData : data ->
+  with (
+    cleaned : str.trim data;
+    normalized : str.lower cleaned;
+    validated : (length normalized) > 0;
+  ) ->
+    when validated is
+      true then Ok normalized
+      _ then Err "Empty data";
+
+// Test 12: Validation examples
+testValidateUserBasic : user ->
+  with (
+    nameValid : (length user.name) > 0;
+    emailValid : (str.length user.email) > 0;  // Simplified validation
+    ageValid : (user.age >= 0) and (user.age <= 150);
+  ) ->
+    (nameValid and emailValid and ageValid);
+
+testValidateUserContact : user ->
+  with (
+    phoneValid : (length user.phone) >= 10;
+  ) ->
+    phoneValid;
+
+testProcessUser : user ->
+  when ((testValidateUserBasic user) and (testValidateUserContact user)) is
+    true then Ok user
+    _ then Err "Validation failed";
+
+// Execute tests
+result1 : testBasicWith 2 5;
+result2 : testTypedWith 3 4;
+result3 : testEvenOdd 10;
+result4 : testQuadraticRoots 1 -5 6;
+result5 : testCalculateTax 75000 10000;
+result6 : testProcessUserData { id: 1, name: "  john doe  ", age: 25, active: true };
+result7 : testValidateOrder { items: [1, 2, 3], total: 100 };
+result8 : testClassifyTriangle 3 4 5;
+result9 : testTreeOperations { left: { left: {}, right: {} }, right: {} };
+result10 : testTrafficLight "red";
+result11 : testCombinatorics 5 2;
+result12 : testProcessData "  Hello World  ";
+result13 : testProcessUser { name: "John", email: "john@example.com", age: 30, phone: "1234567890" };
+
+// Output results
+io.out result1;
+io.out result2;
+io.out result3;
+io.out result4;
+io.out result5;
+io.out result6;
+io.out result7;
+io.out result8;
+io.out result9;
+io.out result10;
+io.out result11;
+io.out result12;
+io.out result13;
diff --git a/js/baba-yaga/scratch/baba/example.baba b/js/baba-yaga/scratch/baba/example.baba
new file mode 100644
index 0000000..2311f86
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/example.baba
@@ -0,0 +1,269 @@
+// This file demonstrates all features of Baba Yaga.
+
+// 1. Comments
+// Single-line comments start with `//`.
+myVar : 10; // Comments can also be at the end of a line.
+
+// 2. Types
+// The language supports Int, Float, String, and Result types.
+myInt : 10;       // Inferred as Int
+myFloat : 3.14;   // Inferred as Float
+myString : "Baba Yaga"; // Inferred as String
+
+// Type declarations are optional but enforced if provided.
+myExplicitInt Int;
+myExplicitInt : 20;
+
+myExplicitString String;
+myExplicitString : "Explicitly typed string.";
+
+// Explicit List and Table type declarations
+myExplicitList List;
+myExplicitList : [1 2 3 4 5];
+
+myExplicitTable Table;
+myExplicitTable : { name: "John" age: 25 city: "New York" };
+
+// 3. Variable and Type Declarations
+// Variables are declared using an identifier followed by a colon and their value.
+// Example: myVariable : value;
+
+// 4. Functions (Anonymous, Currying, Partial Application)
+
+// A simple anonymous function (x -> x + 1)
+addOne : x -> x + 1;
+resultAddOne : addOne 5; // resultAddOne will be 6
+io.out resultAddOne;
+
+// A curried function with type annotations
+multiply : (x: Float) -> (Float -> Float) -> y -> x * y;
+// The type signature here breaks down like:
+// 1. (x: Float)       - First parameter is a Float called x
+// 2. ->               - Returns...
+// 3. (Float -> Float) - A function that takes a Float and returns a Float
+// 4. -> y -> x * y    - The implementation: take y, multiply x by y
+
+// Partial application: create a new function by applying some arguments
+multiplyByTwo : multiply 2.0;
+resultMultiply : multiplyByTwo 7.0; // resultMultiply will be 14.0
+io.out resultMultiply;
+
+// 5. Operators
+// Arithmetic: +, -, *, /, %
+// Comparison: =, >, <, >=, <=
+
+// Arithmetic operations
+sum : 10 + 5;     // 15
+difference : 10 - 5; // 5
+product : 10 * 5;  // 50
+quotient : 10 / 5; // 2
+remainder : 10 % 3; // 1
+
+io.out sum;
+io.out difference;
+io.out product;
+io.out quotient;
+io.out remainder;
+
+// Comparison operations
+isEqual : 10 = 10;   // true
+isGreaterThan : 10 > 5; // true
+isLessThan : 5 < 10;  // true
+isGreaterThanOrEqualTo : 10 >= 10; // true
+isLessThanOrEqualTo : 5 <= 10; // true
+
+io.out isEqual;
+io.out isGreaterThan;
+io.out isLessThan;
+io.out isGreaterThanOrEqualTo;
+io.out isLessThanOrEqualTo;
+
+// 6. Control Flow: The `when` Expression
+
+// Literal Matching
+checkNumber : num ->
+  when num is
+    1 then "One"
+    2 then "Two"
+    _ then "Something else"; // '_' matches any value
+
+resultCheckNumberOne : checkNumber 1; // "One"
+resultCheckNumberThree : checkNumber 3; // "Something else"
+
+io.out resultCheckNumberOne;
+io.out resultCheckNumberThree;
+
+// Multiple Discriminants
+checkCoords : x y ->
+  when x y is
+    0 0 then "Origin"
+    1 1 then "Diagonal"
+    _ _ then "Somewhere else";
+
+resultCheckCoordsOrigin : checkCoords 0 0; // "Origin"
+resultCheckCoordsOther : checkCoords 5 10; // "Somewhere else"
+
+io.out resultCheckCoordsOrigin;
+io.out resultCheckCoordsOther;
+
+// Type Matching
+checkType : val ->
+  when val is
+    Bool   then "It's a Boolean"
+    Int    then "It's an Integer"
+    Float  then "It's a Float"
+    String then "It's a String"
+    List   then "It's a List"
+    Table  then "It's a Table"
+    _      then "Unknown Type";
+
+resultCheckTypeBool : checkType true; // "It's a Boolean"
+resultCheckTypeInt : checkType 123; // "It's an Integer"
+resultCheckTypeFloat : checkType 3.14; // "It's a Float"
+resultCheckTypeString : checkType "abc"; // "It's a String"
+resultCheckTypeList : checkType [1 2 3]; // "It's a List"
+resultCheckTypeTable : checkType { name: "test" }; // "It's a Table"
+
+io.out resultCheckTypeBool;
+io.out resultCheckTypeInt;
+io.out resultCheckTypeFloat;
+io.out resultCheckTypeString;
+io.out resultCheckTypeList;
+io.out resultCheckTypeTable;
+
+// List Pattern Matching
+matchList : list ->
+  when list is
+    [1 2 3] then "Exact List Match"
+    [1 _ 3] then "List with Wildcard Match"
+    _       then "No List Match";
+
+resultMatchListExact : matchList [1 2 3]; // "Exact List Match"
+resultMatchListWildcard : matchList [1 99 3]; // "List with Wildcard Match"
+resultMatchListNoMatch : matchList [4 5 6]; // "No List Match"
+
+io.out resultMatchListExact;
+io.out resultMatchListWildcard;
+io.out resultMatchListNoMatch;
+
+// Table Pattern Matching
+matchTable : table ->
+  when table is
+    { name: "Alice" age: 30 } then "Exact Table Match"
+    { name: "Bob" age: _ } then "Table with Wildcard Value Match"
+    _                       then "No Table Match";
+
+resultMatchTableExact : matchTable { name: "Alice" age: 30 }; // "Exact Table Match"
+resultMatchTableWildcardValue : matchTable { name: "Bob" age: 99 }; // "Table with Wildcard Value Match"
+resultMatchTableNoMatch : matchTable { city: "New York" }; // "No Table Match"
+
+io.out resultMatchTableExact;
+io.out resultMatchTableWildcardValue;
+io.out resultMatchTableNoMatch;
+
+// 7. Error Handling: The `Result` Type
+
+// Function returning a Result type
+divide : x y ->
+  when y is
+    0 then Err "Division by zero is not allowed."
+    _ then Ok (x / y);
+
+resultDivideOk : divide 10 2; // Result: Ok 5
+resultDivideErr : divide 5 0;  // Result: Err "Division by zero is not allowed."
+
+// Extracting values from Result types using 'when'
+finalResultOk : when resultDivideOk is
+  Ok val then val // 'val' binds to the inner value of Ok (5)
+  Err msg then 0; // If error, return 0
+
+finalResultErr : when resultDivideErr is
+  Ok val then 0
+  Err msg then msg; // 'msg' binds to the inner value of Err ("Division by zero...")
+
+io.out finalResultOk;
+io.out finalResultErr;
+
+// 8. Lists
+myListExample : [10 20 30 "hello"];
+
+// Accessing elements by index (0-based)
+firstElement : myListExample.0; // 10
+secondElement : myListExample.1; // 20
+
+io.out myListExample;
+io.out firstElement;
+io.out secondElement;
+
+// 9. Tables
+myTableExample : { name: "Baba Yaga" version: 1.0 isActive: true };
+
+// Accessing properties by key
+userName : myTableExample.name; // "Baba Yaga"
+userVersion : myTableExample.version; // 1.0
+
+io.out myTableExample;
+io.out userName;
+io.out userVersion;
+
+// Function within a Table
+myCalculator : {
+  add: x y -> x + y;
+  subtract: x y -> x - y;
+};
+
+resultTableAdd : myCalculator.add 10 5; // 15
+resultTableSubtract : myCalculator.subtract 10 5; // 5
+
+io.out resultTableAdd;
+io.out resultTableSubtract;
+
+// 10. Higher-Order Functions
+
+// map: Applies a function to each element of a list, returning a new list.
+doubledList : map (x -> x * 2) [1 2 3]; // [2 4 6]
+io.out doubledList;
+
+// filter: Creates a new list containing only elements for which a predicate returns true.
+evenNumbers : filter (x -> x % 2 = 0) [1 2 3 4 5]; // [2 4]
+io.out evenNumbers;
+
+// reduce: Applies a function against an accumulator and each element in the list to reduce it to a single value.
+sumOfList : reduce (acc item -> acc + item) 0 [1 2 3 4]; // 10
+io.out sumOfList;
+
+// 11. Typed Functions with Type Enforcement
+
+// Typed function declarations with parameter and return type annotations
+add : (x: Int, y: Int) -> Int -> x + y;
+multiply : (x: Number, y: Number) -> Number -> x * y;
+greet : (name: String) -> String -> str.concat "Hello " name;
+fullName : (first: String, last: String) -> String -> first .. " " .. last;
+isEven : (n: Int) -> Bool -> n % 2 = 0;
+isPositive : (n: Int) -> Bool -> n > 0;
+
+// Test typed functions
+io.out add 5 3;
+io.out multiply 2.5 3.0;
+io.out greet "World";
+io.out fullName "John" "Doe";
+io.out isEven 4;
+io.out isEven 5;
+io.out isPositive 10;
+io.out isPositive -5;
+
+// 12. String Functions
+
+// Core string operations
+io.out str.length "hello";
+io.out str.upper "hello world";
+io.out str.lower "HELLO WORLD";
+io.out str.split "hello,world,test" ",";
+io.out str.join ["a" "b" "c"] "-";
+io.out str.trim "  hello  ";
+io.out str.substring "hello world" 0 5;
+io.out str.replace "hello hello" "hello" "hi";
+
+// String concatenation with .. operator
+message : "Hello" .. " " .. "World" .. "!";
+io.out message;
diff --git a/js/baba-yaga/scratch/baba/functional-features-demo.baba b/js/baba-yaga/scratch/baba/functional-features-demo.baba
new file mode 100644
index 0000000..c9cb12b
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/functional-features-demo.baba
@@ -0,0 +1,128 @@
+// Functional Programming Features Demo
+// Testing all the new features we've implemented
+
+io.out "=== Testing New Functional Programming Features ===";
+io.out "";
+
+// === Pattern Guards ===
+io.out "1. Pattern Guards:";
+
+classifyNumber : n ->
+  when n is
+    0 then "zero"
+    x if (x > 0) then "positive"
+    x if (x < 0) then "negative"
+    _ then "unknown";
+
+result1 : classifyNumber 5;
+result2 : classifyNumber -3;
+result3 : classifyNumber 0;
+
+io.out ("5 is " .. result1);
+io.out ("-3 is " .. result2);
+io.out ("0 is " .. result3);
+io.out "";
+
+// === Scan Operations ===
+io.out "2. Scan Operations:";
+
+numbers : [1, 2, 3, 4, 5];
+cumulative : cumsum numbers;
+product : cumprod numbers;
+
+addFunc : acc x -> acc + x;
+customScan : scan addFunc 10 numbers;
+
+io.out ("Numbers: " .. numbers);
+io.out ("Cumulative sum: " .. cumulative);
+io.out ("Cumulative product: " .. product);
+io.out ("Custom scan from 10: " .. customScan);
+io.out "";
+
+// === Array Indexing ===
+io.out "3. Array Indexing:";
+
+data : [10, 20, 30, 40, 50];
+indices : [0, 2, 4];
+selected : at indices data;
+
+evenPredicate : x -> x % 2 = 0;
+evenIndices : where evenPredicate data;
+
+firstThree : take 3 data;
+lastTwo : drop 3 data;
+
+io.out ("Data: " .. data);
+io.out ("Selected at [0,2,4]: " .. selected);
+io.out ("Even indices: " .. evenIndices);
+io.out ("First 3: " .. firstThree);
+io.out ("Last 2: " .. lastTwo);
+io.out "";
+
+// === Broadcasting ===
+io.out "4. Broadcasting Operations:";
+
+values : [1, 2, 3, 4];
+addTen : broadcast (a b -> a + b) 10 values;
+
+array1 : [1, 2, 3];
+array2 : [4, 5, 6];
+multiplied : zipWith (a b -> a * b) array1 array2;
+
+flatData : [1, 2, 3, 4, 5, 6];
+matrix : reshape [2, 3] flatData;
+
+io.out ("Values: " .. values);
+io.out ("Add 10 to each: " .. addTen);
+io.out ("Array 1: " .. array1);
+io.out ("Array 2: " .. array2);
+io.out ("Element-wise multiply: " .. multiplied);
+io.out "Reshaped matrix:";
+io.print matrix;
+io.out "";
+
+// === Function Combinators ===
+io.out "5. Function Combinators:";
+
+addOp : x y -> x + y;
+flippedAdd : flip addOp;
+flipResult : flippedAdd 3 7;  // 7 + 3
+
+doubler : x -> x * 2;
+applyResult : apply doubler 5;
+
+tripler : x -> x * 3;
+pipeResult : pipe 4 tripler;
+
+increment : x -> x + 1;
+composed : compose doubler increment;
+composeResult : composed 5;  // (5 + 1) * 2
+
+io.out ("Flip add 3 7: " .. flipResult);
+io.out ("Apply double to 5: " .. applyResult);
+io.out ("Pipe 4 through triple: " .. pipeResult);
+io.out ("Compose increment then double on 5: " .. composeResult);
+io.out "";
+
+// === FlatMap ===
+io.out "6. FlatMap Operations:";
+
+duplicator : x -> [x, x];
+original : [1, 2, 3];
+duplicated : flatMap duplicator original;
+
+io.out ("Original: " .. original);
+io.out ("Duplicated: " .. duplicated);
+io.out "";
+
+// === Summary ===
+io.out "=== Summary ===";
+io.out "All functional programming features working:";
+io.out "✓ Pattern Guards with conditional expressions";
+io.out "✓ Scan operations (scan, cumsum, cumprod)";
+io.out "✓ Array indexing (at, where, take, drop)";
+io.out "✓ Broadcasting (broadcast, zipWith, reshape)";
+io.out "✓ Function combinators (flip, apply, pipe, compose)";
+io.out "✓ Monadic operations (flatMap)";
+io.out "";
+io.out "Baba Yaga now has powerful functional programming capabilities!";
diff --git a/js/baba-yaga/scratch/baba/game-of-life.baba b/js/baba-yaga/scratch/baba/game-of-life.baba
new file mode 100644
index 0000000..2721b3e
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/game-of-life.baba
@@ -0,0 +1,76 @@
+// Conway's Game of Life - Working Implementation
+
+// Count neighbors for a 3x3 grid (hardcoded positions)
+countNeighbors : grid row col ->
+  when row is
+    0 then when col is
+      0 then grid.0.1 + grid.1.0 + grid.1.1
+      1 then grid.0.0 + grid.0.2 + grid.1.0 + grid.1.1 + grid.1.2
+      2 then grid.0.1 + grid.1.1 + grid.1.2
+      _ then 0
+    1 then when col is
+      0 then grid.0.0 + grid.0.1 + grid.1.1 + grid.2.0 + grid.2.1
+      1 then grid.0.0 + grid.0.1 + grid.0.2 + grid.1.0 + grid.1.2 + grid.2.0 + grid.2.1 + grid.2.2
+      2 then grid.0.1 + grid.0.2 + grid.1.1 + grid.2.1 + grid.2.2
+      _ then 0
+    2 then when col is
+      0 then grid.1.0 + grid.1.1 + grid.2.1
+      1 then grid.1.0 + grid.1.1 + grid.1.2 + grid.2.0 + grid.2.2
+      2 then grid.1.1 + grid.1.2 + grid.2.1
+      _ then 0
+    _ then 0;
+
+// Apply Game of Life rules
+nextCell : grid row col ->
+  with (
+    current : when row is
+      0 then when col is 0 then grid.0.0 1 then grid.0.1 2 then grid.0.2 _ then 0
+      1 then when col is 0 then grid.1.0 1 then grid.1.1 2 then grid.1.2 _ then 0
+      2 then when col is 0 then grid.2.0 1 then grid.2.1 2 then grid.2.2 _ then 0
+      _ then 0;
+    neighbors : countNeighbors grid row col;
+  ) ->
+    when current is
+      1 then when (neighbors = 2 or neighbors = 3) is true then 1 _ then 0
+      _ then when (neighbors = 3) is true then 1 _ then 0;
+
+// Generate next generation for 3x3 grid
+step : grid -> {
+  0: {
+    0: nextCell grid 0 0,
+    1: nextCell grid 0 1,
+    2: nextCell grid 0 2
+  },
+  1: {
+    0: nextCell grid 1 0,
+    1: nextCell grid 1 1,
+    2: nextCell grid 1 2
+  },
+  2: {
+    0: nextCell grid 2 0,
+    1: nextCell grid 2 1,
+    2: nextCell grid 2 2
+  }
+};
+
+// Blinker pattern (oscillator)
+blinker : {
+  0: { 0: 0, 1: 1, 2: 0 },
+  1: { 0: 0, 1: 1, 2: 0 },
+  2: { 0: 0, 1: 1, 2: 0 }
+};
+
+// Run simulation
+io.out "Conway's Game of Life - Blinker Pattern";
+io.out "Generation 0:";
+io.out blinker;
+
+gen1 : step blinker;
+io.out "Generation 1:";
+io.out gen1;
+
+gen2 : step gen1;
+io.out "Generation 2:";
+io.out gen2;
+
+io.out "Complete!";
diff --git a/js/baba-yaga/scratch/baba/indentation_test.baba b/js/baba-yaga/scratch/baba/indentation_test.baba
new file mode 100644
index 0000000..3e0a659
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/indentation_test.baba
@@ -0,0 +1,20 @@
+// Test proper indentation
+simpleFunc : x -> x + 1;
+
+complexFunc : x ->
+  when x is
+    0 then "zero"
+    1 then "one"
+    _ then "other";
+
+withFunc : a b ->
+  with (
+    sum : a + b;
+    diff : a - b;
+  ) ->
+    {sum: sum, diff: diff};
+
+varWithWhen :
+  when true is
+    true then "yes"
+    false then "no";
diff --git a/js/baba-yaga/scratch/baba/life-demo-alt.baba b/js/baba-yaga/scratch/baba/life-demo-alt.baba
new file mode 100644
index 0000000..b4c35ce
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/life-demo-alt.baba
@@ -0,0 +1,91 @@
+// Conway's Game of Life Demo
+
+// Simple blinker pattern demonstration
+// Initial state: vertical line of 3 cells
+// Next state: horizontal line of 3 cells
+
+// Generation 0 - vertical blinker
+cell_0_1 : 1;  // top
+cell_1_1 : 1;  // middle  
+cell_2_1 : 1;  // bottom
+
+// All other cells are 0
+cell_0_0 : 0;
+cell_0_2 : 0;
+cell_1_0 : 0;
+cell_1_2 : 0;
+cell_2_0 : 0;
+cell_2_2 : 0;
+
+io.out "Conway's Game of Life - Blinker Demo";
+io.out "====================================";
+
+io.out "Generation 0 (vertical line):";
+io.out "Row 0:";
+io.out cell_0_0;
+io.out cell_0_1;
+io.out cell_0_2;
+io.out "Row 1:";
+io.out cell_1_0;
+io.out cell_1_1;
+io.out cell_1_2;
+io.out "Row 2:";
+io.out cell_2_0;
+io.out cell_2_1;
+io.out cell_2_2;
+
+// Calculate Generation 1
+// For the middle cell (1,1): has 2 vertical neighbors, survives
+// For cells (1,0) and (1,2): each has 3 neighbors, become alive
+// All other cells die or stay dead
+
+// Middle cell (1,1) - count neighbors
+neighbors_1_1 : cell_0_1 + cell_2_1;  // 2 neighbors
+next_1_1 : when (cell_1_1 = 1 and (neighbors_1_1 = 2 or neighbors_1_1 = 3)) is
+  true then 1 _ then 0;
+
+// Left cell (1,0) - count neighbors  
+neighbors_1_0 : cell_0_0 + cell_0_1 + cell_1_1 + cell_2_0 + cell_2_1;  // 3 neighbors
+next_1_0 : when (cell_1_0 = 0 and neighbors_1_0 = 3) is
+  true then 1 _ then 0;
+
+// Right cell (1,2) - count neighbors
+neighbors_1_2 : cell_0_1 + cell_0_2 + cell_1_1 + cell_2_1 + cell_2_2;  // 3 neighbors  
+next_1_2 : when (cell_1_2 = 0 and neighbors_1_2 = 3) is
+  true then 1 _ then 0;
+
+// All other cells in generation 1 will be 0
+next_0_0 : 0;
+next_0_1 : 0;
+next_0_2 : 0;
+next_2_0 : 0;
+next_2_1 : 0;
+next_2_2 : 0;
+
+io.out "";
+io.out "Generation 1 (horizontal line):";
+io.out "Row 0:";
+io.out next_0_0;
+io.out next_0_1;
+io.out next_0_2;
+io.out "Row 1:";
+io.out next_1_0;
+io.out next_1_1;
+io.out next_1_2;
+io.out "Row 2:";
+io.out next_2_0;
+io.out next_2_1;
+io.out next_2_2;
+
+io.out "";
+io.out "Neighbor counts:";
+io.out "Cell (1,1) neighbors:";
+io.out neighbors_1_1;
+io.out "Cell (1,0) neighbors:";
+io.out neighbors_1_0;
+io.out "Cell (1,2) neighbors:";
+io.out neighbors_1_2;
+
+io.out "";
+io.out "The blinker oscillates between vertical and horizontal!";
+io.out "This demonstrates Conway's Game of Life rules.";
diff --git a/js/baba-yaga/scratch/baba/life-demo.baba b/js/baba-yaga/scratch/baba/life-demo.baba
new file mode 100644
index 0000000..b4c35ce
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/life-demo.baba
@@ -0,0 +1,91 @@
+// Conway's Game of Life Demo
+
+// Simple blinker pattern demonstration
+// Initial state: vertical line of 3 cells
+// Next state: horizontal line of 3 cells
+
+// Generation 0 - vertical blinker
+cell_0_1 : 1;  // top
+cell_1_1 : 1;  // middle  
+cell_2_1 : 1;  // bottom
+
+// All other cells are 0
+cell_0_0 : 0;
+cell_0_2 : 0;
+cell_1_0 : 0;
+cell_1_2 : 0;
+cell_2_0 : 0;
+cell_2_2 : 0;
+
+io.out "Conway's Game of Life - Blinker Demo";
+io.out "====================================";
+
+io.out "Generation 0 (vertical line):";
+io.out "Row 0:";
+io.out cell_0_0;
+io.out cell_0_1;
+io.out cell_0_2;
+io.out "Row 1:";
+io.out cell_1_0;
+io.out cell_1_1;
+io.out cell_1_2;
+io.out "Row 2:";
+io.out cell_2_0;
+io.out cell_2_1;
+io.out cell_2_2;
+
+// Calculate Generation 1
+// For the middle cell (1,1): has 2 vertical neighbors, survives
+// For cells (1,0) and (1,2): each has 3 neighbors, become alive
+// All other cells die or stay dead
+
+// Middle cell (1,1) - count neighbors
+neighbors_1_1 : cell_0_1 + cell_2_1;  // 2 neighbors
+next_1_1 : when (cell_1_1 = 1 and (neighbors_1_1 = 2 or neighbors_1_1 = 3)) is
+  true then 1 _ then 0;
+
+// Left cell (1,0) - count neighbors  
+neighbors_1_0 : cell_0_0 + cell_0_1 + cell_1_1 + cell_2_0 + cell_2_1;  // 3 neighbors
+next_1_0 : when (cell_1_0 = 0 and neighbors_1_0 = 3) is
+  true then 1 _ then 0;
+
+// Right cell (1,2) - count neighbors
+neighbors_1_2 : cell_0_1 + cell_0_2 + cell_1_1 + cell_2_1 + cell_2_2;  // 3 neighbors  
+next_1_2 : when (cell_1_2 = 0 and neighbors_1_2 = 3) is
+  true then 1 _ then 0;
+
+// All other cells in generation 1 will be 0
+next_0_0 : 0;
+next_0_1 : 0;
+next_0_2 : 0;
+next_2_0 : 0;
+next_2_1 : 0;
+next_2_2 : 0;
+
+io.out "";
+io.out "Generation 1 (horizontal line):";
+io.out "Row 0:";
+io.out next_0_0;
+io.out next_0_1;
+io.out next_0_2;
+io.out "Row 1:";
+io.out next_1_0;
+io.out next_1_1;
+io.out next_1_2;
+io.out "Row 2:";
+io.out next_2_0;
+io.out next_2_1;
+io.out next_2_2;
+
+io.out "";
+io.out "Neighbor counts:";
+io.out "Cell (1,1) neighbors:";
+io.out neighbors_1_1;
+io.out "Cell (1,0) neighbors:";
+io.out neighbors_1_0;
+io.out "Cell (1,2) neighbors:";
+io.out neighbors_1_2;
+
+io.out "";
+io.out "The blinker oscillates between vertical and horizontal!";
+io.out "This demonstrates Conway's Game of Life rules.";
diff --git a/js/baba-yaga/scratch/baba/life-example.baba b/js/baba-yaga/scratch/baba/life-example.baba
new file mode 100644
index 0000000..7ae7164
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/life-example.baba
@@ -0,0 +1,181 @@
+headAt : xs i ->
+  with (
+    tmp : slice xs i (i + 1);
+  ) ->
+    tmp.0;
+
+get2 : grid r c ->
+  headAt (headAt grid r) c;
+
+safeGet2 : grid r c ->
+  with (
+    rows : length grid;
+    cols : length (headAt grid 0);
+    rOk : r >= 0 and r < rows;
+    cOk : c >= 0 and c < cols;
+  ) ->
+    when rOk and cOk is
+      true then get2 grid r c
+      _    then 0;
+
+range : lo hi ->
+  when lo >= hi is
+    true then []
+    _    then prepend lo (range (lo + 1) hi);
+
+sum : xs ->
+  reduce (acc x -> acc + x) 0 xs;
+
+deltas : [-1, 0, 1];
+
+neighborsValues : grid r c ->
+  reduce (acc dr -> reduce (acc2 dc ->   when dr = 0 and dc = 0 is
+    true then acc2
+    _    then append acc2 (safeGet2 grid (r + dr) (c + dc))) acc deltas) [] deltas;
+
+countNeighbors : grid r c ->
+  sum (neighborsValues grid r c);
+
+nextCell : grid r c ->
+  with (
+    cell : get2 grid r c;
+    n : countNeighbors grid r c;
+    isAlive : cell = 1;
+    born : cell = 0 and n = 3;
+    survive : isAlive and n = 2 or n = 3;
+  ) ->
+    when survive is
+      true then 1
+      _    then 
+        when born is
+          true then 1
+          _    then 0;
+
+rowNext : grid w r ->
+  map (c -> nextCell grid r c) (range 0 w);
+
+step : grid ->
+  with (
+    h : length grid;
+    w : length (headAt grid 0);
+  ) ->
+    map (r -> rowNext grid w r) (range 0 h);
+
+g0 : [
+  [0, 1, 0, 0, 0],
+  [0, 0, 1, 0, 0],
+  [1, 1, 1, 0, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+g1 : step g0;
+g2 : step g1;
+g3 : step g2;
+g4 : step g3;
+blinker0 : [[1, 1, 1], [0, 0, 0], [0, 0, 0]];
+blinker1 : step blinker0;
+blinker2 : step blinker1;
+toad0 : [
+  [0, 1, 1, 1],
+  [1, 1, 1, 0],
+  [0, 0, 0, 0],
+  [0, 0, 0, 0]
+];
+toad1 : step toad0;
+toad2 : step toad1;
+beacon0 : [
+  [1, 1, 0, 0],
+  [1, 1, 0, 0],
+  [0, 0, 1, 1],
+  [0, 0, 1, 1]
+];
+beacon1 : step beacon0;
+beacon2 : step beacon1;
+block : [[1, 1], [1, 1]];
+block1 : step block;
+beehive : [[0, 1, 1, 0], [1, 0, 0, 1], [0, 1, 1, 0]];
+beehive1 : step beehive;
+pulsar0 : [
+  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
+  [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
+  [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0],
+  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+  [0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1],
+  [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
+  [0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 1],
+  [0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0],
+  [0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1],
+  [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0],
+  [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0],
+  [0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]
+];
+pulsar1 : step pulsar0;
+pulsar2 : step pulsar1;
+pulsar3 : step pulsar2;
+
+// Enhanced Conway's Game of Life display using io.print
+io.print "";
+io.print "Conway's Game of Life - Pattern Evolution";
+io.print "==========================================";
+
+io.print "";
+io.print "Glider Pattern Evolution:";
+io.print "Step 0:";
+io.print g0;
+io.print "Step 1:";
+io.print g1;
+io.print "Step 2:";
+io.print g2;
+io.print "Step 3:";
+io.print g3;
+io.print "Step 4:";
+io.print g4;
+
+io.print "";
+io.print "Blinker Oscillation:";
+io.print "Step 0:";
+io.print blinker0;
+io.print "Step 1:";
+io.print blinker1;
+io.print "Step 2:";
+io.print blinker2;
+
+io.print "";
+io.print "Toad Breathing Pattern:";
+io.print "Step 0:";
+io.print toad0;
+io.print "Step 1:";
+io.print toad1;
+io.print "Step 2:";
+io.print toad2;
+
+io.print "";
+io.print "Beacon Blinking:";
+io.print "Step 0:";
+io.print beacon0;
+io.print "Step 1:";
+io.print beacon1;
+io.print "Step 2:";
+io.print beacon2;
+
+io.print "";
+io.print "Still Life Patterns:";
+io.print "Block:";
+io.print block;
+io.print "Beehive:";
+io.print beehive;
+
+io.print "";
+io.print "Pulsar Oscillation (Period 3):";
+io.print "Step 0:";
+io.print pulsar0;
+io.print "Step 1:";
+io.print pulsar1;
+io.print "Step 2:";
+io.print pulsar2;
+io.print "Step 3:";
+io.print pulsar3;
+
+// End of program - visual patterns shown above
diff --git a/js/baba-yaga/scratch/baba/life-final.baba b/js/baba-yaga/scratch/baba/life-final.baba
new file mode 100644
index 0000000..a489c89
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/life-final.baba
@@ -0,0 +1,59 @@
+// Conway's Game of Life - Final Working Demo
+
+// Simple blinker pattern - just show the concept
+
+// Initial state: 3 cells in a vertical line
+top : 1;
+middle : 1;  
+bottom : 1;
+
+io.out "Conway's Game of Life - Blinker Pattern";
+io.out "==========================================";
+
+io.out "Generation 0 (vertical line):";
+io.out "  .#.";
+io.out "  .#.";
+io.out "  .#.";
+
+io.out "";
+io.out "Applying Game of Life rules...";
+
+// Count neighbors for middle cell
+middleNeighbors : top + bottom;  // 2 neighbors (top and bottom)
+
+// Apply rules: live cell with 2-3 neighbors survives
+middleNext : when (middle = 1 and (middleNeighbors = 2 or middleNeighbors = 3)) is
+  true then 1 
+  _ then 0;
+
+// Count neighbors for left and right of middle row (each has 3 neighbors)
+leftNeighbors : 3;  // top, middle, bottom
+rightNeighbors : 3; // top, middle, bottom
+
+// Apply rules: dead cell with exactly 3 neighbors becomes alive
+leftNext : when (leftNeighbors = 3) is true then 1 _ then 0;
+rightNext : when (rightNeighbors = 3) is true then 1 _ then 0;
+
+io.out "Generation 1 (horizontal line):";
+io.out "  ...";
+io.out "  ###";
+io.out "  ...";
+
+io.out "";
+io.out "Neighbor counts:";
+io.out "Middle cell had neighbors:"; io.out middleNeighbors;
+io.out "Middle cell survives:"; io.out middleNext;
+io.out "Left cell becomes alive:"; io.out leftNext;
+io.out "Right cell becomes alive:"; io.out rightNext;
+
+io.out "";
+io.out "The pattern oscillates between:";
+io.out "Vertical:  .#.    Horizontal: ...";
+io.out "           .#.                ###";
+io.out "           .#.                ...";
+
+io.out "";
+io.out "This demonstrates Conway's Game of Life!";
+io.out "Rules: Live cell with 2-3 neighbors survives";
+io.out "       Dead cell with exactly 3 neighbors becomes alive";
+io.out "       All other cells die or stay dead";
diff --git a/js/baba-yaga/scratch/baba/life-simple.baba b/js/baba-yaga/scratch/baba/life-simple.baba
new file mode 100644
index 0000000..b2da07c
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/life-simple.baba
@@ -0,0 +1,51 @@
+// Simple Conway's Game of Life
+
+// Create a simple 3x3 blinker using individual variables
+c00 : 0; c01 : 1; c02 : 0;
+c10 : 0; c11 : 1; c12 : 0;  
+c20 : 0; c21 : 1; c22 : 0;
+
+// Count neighbors for center cell (1,1)
+neighbors11 : c00 + c01 + c02 + c10 + c12 + c20 + c21 + c22;
+
+// Apply Game of Life rules to center cell
+next11 : when (c11 = 1) is
+  true then when (neighbors11 = 2 or neighbors11 = 3) is true then 1 _ then 0
+  _ then when (neighbors11 = 3) is true then 1 _ then 0;
+
+// Count neighbors for top-left cell (0,0)  
+neighbors00 : c01 + c10 + c11;
+
+// Apply rules to top-left cell
+next00 : when (c00 = 1) is
+  true then when (neighbors00 = 2 or neighbors00 = 3) is true then 1 _ then 0
+  _ then when (neighbors00 = 3) is true then 1 _ then 0;
+
+// Count neighbors for top-center cell (0,1)
+neighbors01 : c00 + c02 + c10 + c11 + c12;
+
+// Apply rules to top-center cell  
+next01 : when (c01 = 1) is
+  true then when (neighbors01 = 2 or neighbors01 = 3) is true then 1 _ then 0
+  _ then when (neighbors01 = 3) is true then 1 _ then 0;
+
+// Display results
+io.out "Conway's Game of Life - Blinker Pattern";
+io.out "Generation 0:";
+io.out c00; io.out c01; io.out c02;
+io.out c10; io.out c11; io.out c12;
+io.out c20; io.out c21; io.out c22;
+
+io.out "Generation 1 (center cell):";
+io.out "Center cell neighbors:"; io.out neighbors11;
+io.out "Center cell next state:"; io.out next11;
+
+io.out "Generation 1 (top-left cell):";
+io.out "Top-left neighbors:"; io.out neighbors00;
+io.out "Top-left next state:"; io.out next00;
+
+io.out "Generation 1 (top-center cell):";
+io.out "Top-center neighbors:"; io.out neighbors01;
+io.out "Top-center next state:"; io.out next01;
+
+io.out "Done!";
diff --git a/js/baba-yaga/scratch/baba/life.baba b/js/baba-yaga/scratch/baba/life.baba
new file mode 100644
index 0000000..a5fbe79
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/life.baba
@@ -0,0 +1,90 @@
+// Conway's Game of Life in Baba Yaga
+
+// headAt: return the element at index i from list xs
+headAt : xs i -> with (tmp : slice xs i (i + 1)) -> tmp.0;
+
+// get2: 2D index for a grid (list of lists)
+get2 : grid r c -> headAt (headAt grid r) c;
+
+// safeGet2: bounds-checked 2D get; returns 0 when out of bounds
+safeGet2 : grid r c ->
+  with (
+    rows : length grid;
+    cols : length (headAt grid 0);
+    rOk  : (r >= 0) and (r < rows);
+    cOk  : (c >= 0) and (c < cols);
+  ) ->
+    when (rOk and cOk) is
+      true then get2 grid r c
+      _    then 0;
+
+// range [lo, hi) as a list of Int
+range : lo hi ->
+  when (lo >= hi) is
+    true then []
+    _    then prepend lo (range (lo + 1) hi);
+
+// sum a list of numbers
+sum : xs -> reduce (acc x -> acc + x) 0 xs;
+
+// deltas for neighborhood offsets
+deltas : [-1, 0, 1];
+
+// neighborsValues: list of neighbor cell values for (r,c)
+neighborsValues : grid r c ->
+  reduce (acc dr ->
+    reduce (acc2 dc ->
+      when ((dr = 0) and (dc = 0)) is
+        true then acc2
+        _    then append acc2 (safeGet2 grid (r + dr) (c + dc))
+    ) acc deltas
+  ) [] deltas;
+
+// count live neighbors at (r,c)
+countNeighbors : grid r c -> sum (neighborsValues grid r c);
+
+// nextCell: apply Game of Life rules at (r,c)
+nextCell : grid r c ->
+  with (
+    cell    : get2 grid r c;
+    n       : countNeighbors grid r c;
+    isAlive : cell = 1;
+    born    : (cell = 0) and (n = 3);
+    survive : isAlive and ((n = 2) or (n = 3));
+  ) ->
+    when survive is
+      true then 1
+      _    then when born is true then 1 _ then 0;
+
+// build next row r given width w
+rowNext : grid w r -> map (c -> nextCell grid r c) (range 0 w);
+
+// Single simulation step for the entire grid
+step : grid ->
+  with (
+    h : length grid;
+    w : length (headAt grid 0);
+  ) -> map (r -> rowNext grid w r) (range 0 h);
+
+// Demo: glider pattern in a 5x5 grid
+g0 : [
+  [0, 1, 0, 0, 0],
+  [0, 0, 1, 0, 0],
+  [1, 1, 1, 0, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+
+g1 : step g0;
+g2 : step g1;
+g3 : step g2;
+g4 : step g3;
+
+// Print successive generations
+io.out g0;
+io.out g1;
+io.out g2;
+io.out g3;
+io.out g4;
+
+
diff --git a/js/baba-yaga/scratch/baba/nested_when_test.baba b/js/baba-yaga/scratch/baba/nested_when_test.baba
new file mode 100644
index 0000000..a626634
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/nested_when_test.baba
@@ -0,0 +1,30 @@
+// Test deeply nested when expressions
+classify : x y ->
+  when x is
+    0 then when y is
+             0 then "origin"
+             1 then "y-axis"
+             _ then when y > 0 is
+                     true then "positive y-axis"
+                     false then "negative y-axis"
+    1 then when y is
+             0 then "x-axis"
+             1 then "diagonal"
+             _ then when y > 0 is
+                     true then when y > 10 is
+                             true then "far positive diagonal"
+                             false then "close positive diagonal"
+                     false then "negative diagonal"
+    _ then "other quadrant";
+
+// Test with multiple discriminants and nesting
+complexCase : a b c ->
+  when a b is
+    0 0 then when c is
+               1 then "case 1"
+               2 then when true is
+                        true then "nested true"
+                        false then "nested false"
+               _ then "default c"
+    1 _ then "partial match"
+    _ _ then "catch all";
diff --git a/js/baba-yaga/scratch/baba/nested_when_working.baba b/js/baba-yaga/scratch/baba/nested_when_working.baba
new file mode 100644
index 0000000..9552632
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/nested_when_working.baba
@@ -0,0 +1,12 @@
+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";
diff --git a/js/baba-yaga/scratch/baba/simple.baba b/js/baba-yaga/scratch/baba/simple.baba
new file mode 100644
index 0000000..e0f0b33
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/simple.baba
@@ -0,0 +1,8 @@
+x : 2 + 3;
+io.out x;
+inc : a -> a + 1;
+io.out (inc 4);
+y : when 1 is
+  1 then 10
+  _ then 20;
+io.out y;
diff --git a/js/baba-yaga/scratch/baba/simple_nested_when.baba b/js/baba-yaga/scratch/baba/simple_nested_when.baba
new file mode 100644
index 0000000..7f7a258
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/simple_nested_when.baba
@@ -0,0 +1,8 @@
+// Simple nested when test
+test : x ->
+  when x is
+    0 then when true is
+             true then "nested true"
+             false then "nested false"
+    1 then "simple case"
+    _ then "default";
diff --git a/js/baba-yaga/scratch/baba/test_comprehensive_features.baba b/js/baba-yaga/scratch/baba/test_comprehensive_features.baba
new file mode 100644
index 0000000..7a205b1
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_comprehensive_features.baba
@@ -0,0 +1,87 @@
+// Comprehensive test combining all new functional programming features
+
+io.out "=== Comprehensive Feature Test ===";
+
+// Example: Processing student data with advanced functional programming
+
+// Sample student data
+students : [
+  {name: "Alice", scores: [85, 92, 78, 90]},
+  {name: "Bob", scores: [75, 88, 82, 79]},
+  {name: "Charlie", scores: [95, 96, 94, 97]},
+  {name: "Diana", scores: [65, 70, 68, 72]}
+];
+
+// Calculate average score
+calculateAverage : scores ->
+  with (
+    total : reduce (acc x -> acc + x) 0 scores;
+    count : length scores;
+  ) ->
+    total / count;
+
+// Process each student using flatMap and array operations
+processStudent : student ->
+  with (
+    scores : student.scores;
+    average : calculateAverage scores;
+    cumulative : cumsum scores;
+    
+    // Use pattern guards to assign grades
+    grade : when average is
+      a if (a >= 90) then "A"
+      a if (a >= 80 and a < 90) then "B"  
+      a if (a >= 70 and a < 80) then "C"
+      a if (a >= 60 and a < 70) then "D"
+      a if (a < 60) then "F"
+      _ then "Invalid";
+    
+    // Use broadcasting to normalize scores
+    maxScore : reduce (acc x -> math.max acc x) 0 scores;
+    normalized : broadcast (score max -> score / max * 100) maxScore scores;
+  ) ->
+    {
+      name: student.name,
+      average: average,
+      grade: grade,
+      cumulative: cumulative,
+      normalized: normalized
+    };
+
+// Process all students
+processedStudents : map processStudent students;
+
+io.out "Processed Students:";
+io.out processedStudents;
+
+// Advanced analysis using array programming
+io.out "=== Advanced Analysis ===";
+
+// Extract all scores using flatMap
+allScores : flatMap (s -> s.scores) students;
+io.out "All scores:";
+io.out allScores;
+
+// Find top performers using where and at
+highScoreIndices : where (score -> score >= 90) allScores;
+highScores : at highScoreIndices allScores;
+io.out "High scores (>=90):";
+io.out highScores;
+
+// Use zipWith to compare consecutive students
+studentNames : map (s -> s.name) processedStudents;
+studentAverages : map (s -> s.average) processedStudents;
+
+// Reshape data into matrix for analysis
+scoresMatrix : reshape [4, 4] allScores;
+io.out "Scores as 4x4 matrix:";
+io.print scoresMatrix;
+
+// Combine multiple operations in a pipeline
+topStudents : filter (s -> s.average >= 85) processedStudents;
+topStudentAnalysis : sort.by topStudents (s -> s.average);
+
+io.out "Top students (avg >= 85), sorted by average:";
+io.out topStudentAnalysis;
+
+io.out "=== All comprehensive tests completed ===";
diff --git a/js/baba-yaga/scratch/baba/test_error_docs.baba b/js/baba-yaga/scratch/baba/test_error_docs.baba
new file mode 100644
index 0000000..2efef40
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_error_docs.baba
@@ -0,0 +1,40 @@
+// Test some examples from the error handling documentation
+
+io.out "Testing error handling documentation examples...";
+
+// Basic Result usage
+divide : x y ->
+  when y is
+    0 then Err "Division by zero"
+    _ then Ok (x / y);
+
+handleDivision : x y ->
+  when (divide x y) is
+    Ok result then result
+    Err message then 0;
+
+io.out "Division test:";
+io.out (handleDivision 10 2);    // Should be 5
+io.out (handleDivision 10 0);    // Should be 0
+
+// Validation patterns
+validateAge : age ->
+  when (validate.type "Int" age) is
+    false then Err "Age must be an integer"
+    true then
+      when (validate.range 0 150 age) is
+        false then Err "Age must be between 0 and 150"
+        true then Ok age;
+
+io.out "Validation test:";
+io.out (validateAge 25);         // Should be Ok 25
+io.out (validateAge 200);        // Should be error
+
+// Simple assertion
+assert (2 + 2 = 4) "Math works";
+io.out "Assertion passed!";
+
+// Debug example  
+debug.print "Debug test" 42;
+
+io.out "Error handling documentation examples work!";
diff --git a/js/baba-yaga/scratch/baba/test_error_handling.baba b/js/baba-yaga/scratch/baba/test_error_handling.baba
new file mode 100644
index 0000000..d886e09
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_error_handling.baba
@@ -0,0 +1,47 @@
+// Test error handling patterns from the documentation
+
+io.out "=== Testing Error Handling Patterns ===";
+
+// Basic Result usage
+divide : x y ->
+  when y is
+    0 then Err "Division by zero"
+    _ then Ok (x / y);
+
+handleDivision : x y ->
+  when (divide x y) is
+    Ok result then result
+    Err message then 0;
+
+io.out "Division results:";
+io.out (handleDivision 10 2);    // Should be 5
+io.out (handleDivision 10 0);    // Should print error and return 0
+
+// Validation patterns
+validateAge : age ->
+  when (validate.type "Int" age) is
+    false then Err "Age must be an integer"
+    true then
+      when (validate.range 0 150 age) is
+        false then Err "Age must be between 0 and 150"
+        true then Ok age;
+
+io.out "";
+io.out "Validation results:";
+io.out (validateAge 25);         // Should be Ok 25
+io.out (validateAge 200);        // Should be Err message
+io.out (validateAge "not a number"); // Should be Err message
+
+// Simple assertion example
+io.out "";
+io.out "Assertion example:";
+assert (2 + 2 = 4) "Math works";
+io.out "Assertion passed!";
+
+// Debug example
+io.out "";
+io.out "Debug example:";
+debug.print "Testing debug output" 42;
+
+io.out "";
+io.out "Error handling tests completed!";
diff --git a/js/baba-yaga/scratch/baba/test_functional_enhancements.baba b/js/baba-yaga/scratch/baba/test_functional_enhancements.baba
new file mode 100644
index 0000000..e8e922a
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_functional_enhancements.baba
@@ -0,0 +1,132 @@
+// Test file for new functional programming enhancements
+// This file tests: scan operations, indexing operations, combinators, and flatMap
+
+io.out "=== Testing Scan Operations ===";
+
+// Test basic scan operation
+numbers : [1, 2, 3, 4, 5];
+addFunc : acc x -> acc + x;
+scanned : scan addFunc 0 numbers;
+io.out "scan (+) 0 [1,2,3,4,5]:";
+io.out scanned; // Should be [0, 1, 3, 6, 10, 15]
+
+// Test cumsum utility
+cumsumResult : cumsum numbers;
+io.out "cumsum [1,2,3,4,5]:";
+io.out cumsumResult; // Should be [0, 1, 3, 6, 10, 15]
+
+// Test cumprod utility
+cumprodResult : cumprod numbers;
+io.out "cumprod [1,2,3,4,5]:";
+io.out cumprodResult; // Should be [1, 1, 2, 6, 24, 120]
+
+io.out "=== Testing Array Indexing Operations ===";
+
+data : [10, 21, 30, 43, 50];
+
+// Test 'at' operation
+indices : [0, 2, 4];
+selected : at indices data;
+io.out "at [0,2,4] [10,21,30,43,50]:";
+io.out selected; // Should be [10, 30, 50]
+
+// Test 'where' operation
+evenPredicate : x -> x % 2 = 0;
+evenIndices : where evenPredicate data;
+io.out "where (even?) [10,21,30,43,50]:";
+io.out evenIndices; // Should be [0, 2, 4] (indices of 10, 30, 50)
+
+// Test 'take' operation
+firstThree : take 3 data;
+io.out "take 3 [10,21,30,43,50]:";
+io.out firstThree; // Should be [10, 21, 30]
+
+// Test 'drop' operation
+lastTwo : drop 3 data;
+io.out "drop 3 [10,21,30,43,50]:";
+io.out lastTwo; // Should be [43, 50]
+
+io.out "=== Testing Function Combinators ===";
+
+// Test basic functions for combinators
+add : x y -> x + y;
+multiply : x y -> x * y;
+double : x -> x * 2;
+increment : x -> x + 1;
+
+// Test flip
+flippedAdd : flip add;
+result1 : flippedAdd 3 5; // Should be 5 + 3 = 8
+io.out "flip add 3 5:";
+io.out result1;
+
+// Test apply
+result2 : apply double 7; // Should be 14
+io.out "apply double 7:";
+io.out result2;
+
+// Test pipe
+result3 : pipe 5 double; // Should be 10
+io.out "pipe 5 double:";
+io.out result3;
+
+// Test compose
+composed : compose increment double; // x -> (x * 2) + 1
+result4 : composed 4; // Should be 9
+io.out "compose increment double 4:";
+io.out result4;
+
+io.out "=== Testing flatMap ===";
+
+// Test flatMap with simple function
+duplicateFunc : x -> [x, x];
+original : [1, 2, 3];
+duplicated : flatMap duplicateFunc original;
+io.out "flatMap (x -> [x,x]) [1,2,3]:";
+io.out duplicated; // Should be [1, 1, 2, 2, 3, 3]
+
+// Test flatMap with range generation
+rangeFunc : x -> range 1 x;
+rangeResult : flatMap rangeFunc [2, 3];
+io.out "flatMap (x -> range 1 x) [2,3]:";
+io.out rangeResult; // Should be [1, 2, 1, 2, 3]
+
+io.out "=== Combining Operations ===";
+
+// Complex example: Find cumulative sums of doubled even numbers
+evenNumbers : [2, 4, 6, 8];
+doubled : map double evenNumbers;
+cumulative : cumsum doubled;
+io.out "Cumsum of doubled evens [2,4,6,8]:";
+io.out cumulative; // [0, 4, 12, 24, 40]
+
+// Using combinators in a pipeline-like fashion
+processNumber : x -> pipe x (compose increment double);
+processed : map processNumber [1, 2, 3];
+io.out "Map (pipe x (compose inc double)) [1,2,3]:";
+io.out processed; // Should be [3, 5, 7]
+
+io.out "=== Testing Broadcasting Operations ===";
+
+// Test broadcast (scalar-array operation)
+addOp : x y -> x + y;
+numbers2 : [1, 2, 3, 4];
+broadcasted : broadcast addOp 10 numbers2;
+io.out "broadcast (+) 10 [1,2,3,4]:";
+io.out broadcasted; // Should be [11, 12, 13, 14]
+
+// Test zipWith (element-wise array-array operation)
+array1 : [1, 2, 3];
+array2 : [10, 20, 30];
+zipped : zipWith addOp array1 array2;
+io.out "zipWith (+) [1,2,3] [10,20,30]:";
+io.out zipped; // Should be [11, 22, 33]
+
+// Test reshape (2D matrix creation)
+flatArray : [1, 2, 3, 4, 5, 6];
+matrixShape : [2, 3]; // 2 rows, 3 columns
+matrix : reshape matrixShape flatArray;
+io.out "reshape [2,3] [1,2,3,4,5,6]:";
+io.print matrix; // Should display as 2x3 matrix
+
+io.out "=== All tests completed ===";
diff --git a/js/baba-yaga/scratch/baba/test_grid_display.baba b/js/baba-yaga/scratch/baba/test_grid_display.baba
new file mode 100644
index 0000000..037230e
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_grid_display.baba
@@ -0,0 +1,20 @@
+// Test grid display
+showCell : cell ->
+  when cell is
+    1 then "█"
+    _ then "·";
+
+showRow : row ->
+  reduce (acc cell -> str.concat acc (showCell cell)) "" row;
+
+showGrid : grid ->
+  reduce (acc row -> str.concat acc (str.concat (showRow row) "\n")) "" grid;
+
+testGrid : [
+  [1, 0, 1],
+  [0, 1, 0],
+  [1, 0, 1]
+];
+
+io.out "Test Grid:";
+io.out showGrid testGrid;
diff --git a/js/baba-yaga/scratch/baba/test_io_print.baba b/js/baba-yaga/scratch/baba/test_io_print.baba
new file mode 100644
index 0000000..4623089
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_io_print.baba
@@ -0,0 +1,34 @@
+// Test the new io.print functionality
+
+// Simple grid for testing
+testGrid : [
+  [1, 0, 1],
+  [0, 1, 0],
+  [1, 0, 1]
+];
+
+// Test basic grid printing
+io.print "Testing io.print with automatic grid detection:";
+io.print testGrid;
+
+io.print "";
+io.print "Testing explicit grid format:";
+io.print "grid" testGrid;
+
+io.print "";
+io.print "Testing regular data:";
+io.print "Number" 42;
+io.print "String" "Hello World";
+
+// Test with a larger grid (like from Game of Life)
+glider : [
+  [0, 1, 0, 0, 0],
+  [0, 0, 1, 0, 0],
+  [1, 1, 1, 0, 0],
+  [0, 0, 0, 0, 0],
+  [0, 0, 0, 0, 0]
+];
+
+io.print "";
+io.print "Conway's Game of Life - Glider Pattern:";
+io.print glider;
diff --git a/js/baba-yaga/scratch/baba/test_logical_and.baba b/js/baba-yaga/scratch/baba/test_logical_and.baba
new file mode 100644
index 0000000..0b2b565
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_logical_and.baba
@@ -0,0 +1,7 @@
+// Test logical and in when discriminant
+test : x y ->
+  when x and y is
+    true then "both true"
+    false then "at least one false";
+
+result : test true false;
diff --git a/js/baba-yaga/scratch/baba/test_pattern_guards.baba b/js/baba-yaga/scratch/baba/test_pattern_guards.baba
new file mode 100644
index 0000000..8b8e2cd
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_pattern_guards.baba
@@ -0,0 +1,57 @@
+// Test file for pattern guards
+io.out "=== Testing Pattern Guards ===";
+
+// Test basic guard with literal pattern
+classifyNumber : n ->
+  when n is
+    0 if n = 0 then "exactly zero"
+    n if n > 0 then "positive"
+    n if n < 0 then "negative"
+    _ then "unknown";
+
+io.out "classifyNumber 5:";
+io.out (classifyNumber 5); // Should be "positive"
+
+io.out "classifyNumber -3:";
+io.out (classifyNumber -3); // Should be "negative"
+
+io.out "classifyNumber 0:";
+io.out (classifyNumber 0); // Should be "exactly zero"
+
+// Test guard with range conditions (avoiding .. operator)
+categorizeAge : age ->
+  when age is
+    a if (a >= 0 and a < 18) then "minor"
+    a if (a >= 18 and a < 65) then "adult"
+    a if (a >= 65) then "senior"
+    _ then "invalid";
+
+io.out "categorizeAge 16:";
+io.out (categorizeAge 16); // Should be "minor"
+
+io.out "categorizeAge 30:";
+io.out (categorizeAge 30); // Should be "adult"
+
+io.out "categorizeAge 70:";
+io.out (categorizeAge 70); // Should be "senior"
+
+// Test guard 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";
+
+io.out "gradeStudent 95:";
+io.out (gradeStudent 95); // Should be "A"
+
+io.out "gradeStudent 75:";
+io.out (gradeStudent 75); // Should be "C"
+
+io.out "gradeStudent 45:";
+io.out (gradeStudent 45); // Should be "F"
+
+io.out "=== Pattern Guards Tests Completed ===";
diff --git a/js/baba-yaga/scratch/baba/test_then_alignment.baba b/js/baba-yaga/scratch/baba/test_then_alignment.baba
new file mode 100644
index 0000000..42b3072
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_then_alignment.baba
@@ -0,0 +1,18 @@
+// Test then alignment
+checkNumber : num ->
+  when num is
+    1 then "One"
+    2 then "Two" 
+    10 then "Ten"
+    100 then "One Hundred"
+    _ then "Something else";
+
+// Test with nested when
+classify : n ->
+  when n is
+    0 then "zero"
+    _ then when n > 100 is
+            true then "large"
+            _    then when n > 10 is
+                        true then "medium"
+                        _    then "small";
diff --git a/js/baba-yaga/scratch/baba/test_utilities.baba b/js/baba-yaga/scratch/baba/test_utilities.baba
new file mode 100644
index 0000000..1245e8a
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/test_utilities.baba
@@ -0,0 +1,106 @@
+// Test file for new utility functions
+
+io.out "Testing new Baba Yaga utilities...";
+io.out "";
+
+// Test validate namespace
+io.out "=== Testing validate.* functions ===";
+io.out (validate.notEmpty "hello");        // true
+io.out (validate.notEmpty "");             // false
+io.out (validate.notEmpty [1, 2, 3]);      // true
+io.out (validate.notEmpty []);             // false
+
+io.out (validate.range 1 10 5);            // true
+io.out (validate.range 1 10 15);           // false
+
+io.out (validate.email "test@example.com"); // true
+io.out (validate.email "invalid-email");    // false
+
+io.out (validate.type "Int" 42);           // true
+io.out (validate.type "String" 42);        // false
+
+io.out "";
+
+// Test text namespace
+io.out "=== Testing text.* functions ===";
+lines : text.lines "hello\nworld\ntest";
+io.out lines;                            // ["hello", "world", "test"]
+
+words : text.words "hello   world  test";
+io.out words;                            // ["hello", "world", "test"]
+
+io.out (text.padLeft 10 "hi");             // "        hi"
+io.out (text.padRight 10 "hi");            // "hi        "
+
+io.out "";
+
+// Test utility functions
+io.out "=== Testing utility functions ===";
+numbers : [1, 2, 3, 4, 5, 6];
+chunks : chunk numbers 2;
+io.out chunks;                           // [[1, 2], [3, 4], [5, 6]]
+
+rangeList : range 1 5;
+io.out rangeList;                        // [1, 2, 3, 4, 5]
+
+repeated : repeat 3 "hello";
+io.out repeated;                         // ["hello", "hello", "hello"]
+
+io.out "";
+
+// Test sort namespace
+io.out "=== Testing sort.by ===";
+people : [
+  {name: "Alice", age: 30},
+  {name: "Bob", age: 25},
+  {name: "Charlie", age: 35}
+];
+
+sortedByAge : sort.by people (p -> p.age);
+io.out sortedByAge;
+
+io.out "";
+
+// Test group namespace
+io.out "=== Testing group.by ===";
+grouped : group.by people (p -> p.age > 25);
+io.out grouped;
+
+io.out "";
+
+// Test random namespace
+io.out "=== Testing random.* functions ===";
+testList : [1, 2, 3, 4, 5];
+choice : random.choice testList;
+io.out choice;                           // random element
+
+shuffled : random.shuffle testList;
+io.out shuffled;                         // shuffled version
+
+randomNum : random.range 1 10;
+io.out randomNum;                        // random number 1-10
+
+io.out "";
+
+// Test debug namespace
+io.out "=== Testing debug functions ===";
+testFunc : x -> x * 2;
+debug.print testFunc;
+debug.print people;
+debug.print 42;
+
+inspection : debug.inspect testFunc;
+io.out inspection;
+
+io.out "";
+
+// Test assert function
+io.out "=== Testing assert ===";
+assert (2 + 2 = 4) "Math works!";
+io.out "Assert passed - math works!";
+
+// This should throw an error if uncommented:
+// assert (2 + 2 = 5) "This will fail";
+
+io.out "";
+io.out "All utility tests completed successfully!";
diff --git a/js/baba-yaga/scratch/baba/then_alignment_demo.baba b/js/baba-yaga/scratch/baba/then_alignment_demo.baba
new file mode 100644
index 0000000..4a4ce35
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/then_alignment_demo.baba
@@ -0,0 +1,27 @@
+processRequest : method path -> 
+when method path is
+  "GET" "/"                    then "Home page"
+  "GET" "/about"               then "About page"
+  "POST" "/api/users"          then "Create user"
+  "DELETE" "/api/users"        then "Delete user"
+  "PATCH" "/api/users/profile" then "Update profile"
+  _ _                          then "Not found";
+
+analyzeData : type value -> 
+when type is
+  "number" then 
+    when value > 0 is
+      true then 
+        when value > 1000 is
+          true     then "large positive"
+          false    then "small positive"
+          false    then "negative or zero"
+          "string" then 
+            when length value > 10 is
+              true      then "long string"
+              false     then "short string"
+              "boolean" then 
+                when value is
+                  true  then "truthy"
+                  false then "falsy"
+                  _     then "unknown type";
diff --git a/js/baba-yaga/scratch/baba/with.baba b/js/baba-yaga/scratch/baba/with.baba
new file mode 100644
index 0000000..05de150
--- /dev/null
+++ b/js/baba-yaga/scratch/baba/with.baba
@@ -0,0 +1,217 @@
+// with.baba — Dev playground and implementation plan for header `with` locals
+//
+// This file documents the proposed `with` and `with rec` header clauses for
+// local bindings inside function bodies. It contains:
+// - Syntax and semantics
+// - Typing rules (locals treated like globals)
+// - Semicolon policy
+// - Examples (untyped, typed, shadowing, with `when`, mutual recursion)
+// - Error cases
+// - Implementation plan (lexer, parser, interpreter, tests)
+//
+// NOTE: All examples are commented out so this file remains parseable until the
+// feature is implemented.
+
+// -----------------------------------------------------------------------------
+// Syntax
+//
+// Function declaration (untyped params):
+//   name : params -> with ( headerEntries ) -> body;
+//
+// Function declaration (typed params + return type):
+//   name : (x: T, y: U) -> R -> with ( headerEntries ) -> body;
+//
+// Header entries inside `with ( ... )` are separated by semicolons `;` and may
+// end with an optional trailing semicolon.
+// Each entry is either:
+//   - Type declaration (same style as global):
+//       ident Type;
+//   - Assignment (value):
+//       ident : expression;
+//
+// Mutually recursive locals use `with rec` (or `with recursion`) to pre-bind:
+//   name : args -> ...
+//     with rec (
+//       f : a -> ... g ...;
+//       g : b -> ... f ...;
+//     ) ->
+//       body;
+//
+// Soft keywords:
+// - `with` and `rec` are recognized only in the function-header position
+//   (immediately after an arrow). Elsewhere they remain plain identifiers.
+
+// -----------------------------------------------------------------------------
+// Semantics
+//
+// with (non-rec):
+// - Create an inner scope layered over the function call scope.
+// - Process header entries left-to-right:
+//   - Type decl: record `name -> Type` in the with-scope types map.
+//   - Assignment: evaluate expression in the current with-scope, then
+//     if a type was declared for `name`, validate using the existing runtime
+//     type lattice (Int ⊂ Float ⊂ Number). Bind `name` to the result.
+// - Evaluate `body` in that inner scope; discard the scope after.
+// - No forward references among assignments.
+// - Shadowing permitted (locals shadow params/globals).
+//
+// with rec (mutual recursion):
+// - Pre-bind all names in the header to placeholders in the with-scope.
+// - Evaluate each RHS in order and assign into the same with-scope.
+// - Restrict RHS to functions (to avoid non-lazy cycles). If non-function is
+//   assigned under `rec`, throw a clear error.
+// - Body executes after all bindings are assigned.
+
+// -----------------------------------------------------------------------------
+// Semicolons
+// - Inside `with ( ... )`: semicolons separate entries; trailing `;` allowed.
+// - Between header and body: only the arrow `->`.
+// - After `body`: same as today at top-level (semicolon optional/tolerated).
+
+// -----------------------------------------------------------------------------
+// Executable Examples
+
+// 1) Basic locals (untyped)
+addMul : x y ->
+  with (inc : x + 1; prod : inc * y;) ->
+    inc + prod;
+addMulResult : addMul 2 5;
+
+// 2) Quadratic roots (untyped)
+quadraticRoots : a b c ->
+  with (
+    disc : b * b - 4 * a * c;
+    sqrtDisc : math.sqrt disc;
+    denom : 2 * a;
+  ) ->
+    { r1: (-b + sqrtDisc) / denom, r2: (-b - sqrtDisc) / denom };
+roots : quadraticRoots 1 -3 2;
+
+// 3) Typed params + typed locals (global-like declarations inside header)
+sumNext : (x: Int, y: Int) -> Int ->
+  with (
+    nextX Int; nextY Int;
+    nextX : x + 1;
+    nextY : y + 1;
+  ) ->
+    nextX + nextY;
+sumNextResult : sumNext 2 3;
+
+// 4) Shadowing and ordering
+shadow : x ->
+  with (x : x + 1; y : x * 2) ->
+    x + y;
+shadowResult : shadow 3;
+
+// 5) With + when
+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";
+classify0 : classify 0;
+classify50 : classify 50;
+classify200 : classify 200;
+
+// Multi-discriminant with local
+bucket : x y ->
+  with (t : x + y) ->
+    when x t is
+      0 0 then "origin"
+      _ _ then "other";
+bucketResult : bucket 0 0;
+
+// 6) Result + with + when
+safeDivide : x y ->
+  with (zero : 0) ->
+    when y is
+      0 then Err "Division by zero"
+      _ then Ok (x / y);
+
+useDivide : a b ->
+  with (fallback Int; fallback : 0) ->
+    when (safeDivide a b) is
+      Ok v  then v
+      Err _ then fallback;
+divOk : useDivide 10 2;
+divErr : useDivide 10 0;
+
+// 7) with rec — mutual recursion among locals
+isEvenOdd : z ->
+  with rec (
+    isEven : n ->
+      when n is
+        0 then true
+        _ then isOdd (n - 1);
+    isOdd : n ->
+      when n is
+        0 then false
+        _ then isEven (n - 1);
+  ) ->
+    { even: isEven 10, odd: isOdd 7 };
+rEvenOdd : isEvenOdd 0;
+
+// Sample I/O to visualize outputs when running this file directly
+io.out addMulResult;
+io.out roots;
+io.out sumNextResult;
+io.out shadowResult;
+io.out classify0 classify50 classify200;
+io.out bucketResult;
+io.out divOk divErr;
+io.out rEvenOdd;
+
+// -----------------------------------------------------------------------------
+// Error cases (intended)
+// - Non-rec forward reference among assignments in `with`: error.
+// - In `with rec`, assignment RHS must evaluate to a function: error otherwise.
+// - Type mismatch for a typed local: reuse existing error messaging similar to
+//   function parameter/return mismatches.
+
+// -----------------------------------------------------------------------------
+// Implementation plan
+// 1) Lexer (none/minimal):
+//    - Keep `with` / `rec` as IDENTIFIER tokens; treat as soft keywords in parser.
+//
+// 2) Parser (parser.js):
+//    - After params and optional return type, detect: IDENT('with') [IDENT('rec'|'recursion')] LPAREN ... RPAREN ARROW
+//    - Parse header entries list:
+//        entry := IDENT TYPE ';'  |  IDENT ':' expression ';'
+//        allow repeated entries and optional trailing ';'
+//    - AST: augment FunctionDeclaration/CurriedFunctionDeclaration body with optional
+//      WithHeader { recursive: boolean, entries: Array< TypeDecl | Assign > }
+//      where TypeDecl { name, typeAnnotation }, Assign { name, expr }
+//    - Ensure support both in top-level function and nested curried bodies.
+//
+// 3) Interpreter (interpreter.js):
+//    - When invoking a function with WithHeader:
+//        - Create with-scope Map layered over call-scope; maintain withTypes Map.
+//        - If recursive:
+//            - Pre-bind all names to undefined in with-scope.
+//            - Evaluate each Assign RHS with with-scope in effect; verify RHS is Function; set binding.
+//          Else:
+//            - Process entries left-to-right: on TypeDecl store in withTypes; on Assign evaluate and bind.
+//        - On each Assign, if a type exists in withTypes, validate via existing lattice.
+//        - Evaluate body in with-scope; finally restore original scope.
+//
+// 4) Tests (tests/*.test.js):
+//    - parser-with-header.test.js (new): parsing of with/with rec, typed locals, trailing semicolon, shadowing, disallow forward refs.
+//    - interpreter-with-header.test.js (new):
+//        * Basic untyped locals
+//        * Typed locals pass and fail
+//        * With + when interactions
+//        * Shadowing behavior
+//        * with rec mutual recursion (success), non-function RHS (error)
+//    - Back-compat pass: ensure existing tests still green.
+//
+// 5) Docs:
+//    - Update README and ref.txt with the new form, semicolon policy, and examples.
+
+