about summary refs log tree commit diff stats
path: root/js/baba-yaga/scratch/baba/crash-course-code.baba
blob: bae2810d2d3434e5a61f0866ca091a740c7b1388 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
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;