@mojir/lits 2.1.34 → 2.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -68,7 +68,7 @@ let squares = [1, 2, 3, 4, 5] map square;
68
68
  // => [1, 4, 9, 16, 25]
69
69
 
70
70
  // Using operator as a function
71
- let sum = +([1, 2, 3, 4, 5]);
71
+ let sum = +(1, 2, 3, 4, 5);
72
72
  // => 15
73
73
  ```
74
74
 
@@ -78,31 +78,31 @@ let sum = +([1, 2, 3, 4, 5]);
78
78
 
79
79
  ```lits
80
80
  // Numbers
81
- 42 // integer
82
- 3.14 // float
83
- 0xFFFF // hexadecimal
84
- 0b1100 // binary
85
- 0o77 // octal
86
- -2.3e-2 // scientific notation
81
+ 42; // integer
82
+ 3.14; // float
83
+ 0xFFFF; // hexadecimal
84
+ 0b1100; // binary
85
+ 0o77; // octal
86
+ -2.3e-2; // scientific notation
87
87
 
88
88
  // Strings
89
- "Hello, world!"
89
+ "Hello, world!";
90
90
 
91
91
  // Booleans
92
- true
93
- false
92
+ true;
93
+ false;
94
94
 
95
95
  // Null
96
- null
96
+ null;
97
97
 
98
98
  // Arrays
99
- [1, 2, 3, 4]
99
+ [1, 2, 3, 4];
100
100
 
101
101
  // Objects
102
- { name: "John", age: 30 }
102
+ { name: "John", age: 30 };
103
103
 
104
104
  // Regular expressions
105
- #"pattern"
105
+ #"pattern";
106
106
  ```
107
107
 
108
108
  ### Mathematical Constants
@@ -110,26 +110,23 @@ null
110
110
  Lits provides predefined mathematical constants:
111
111
 
112
112
  ```lits
113
- PI // => 3.141592653589793
114
- π // => 3.141592653589793 (Unicode alternative)
115
- E // => 2.718281828459045 (Euler's number)
116
- ε // => 2.718281828459045 (Unicode alternative)
117
- PHI // => 1.618033988749895 (Golden ratio)
118
- φ // => 1.618033988749895 (Unicode alternative)
113
+ PI; // => 3.141592653589793
114
+ π; // => 3.141592653589793 (Unicode alternative)
115
+ E; // => 2.718281828459045 (Euler's number)
116
+ ε; // => 2.718281828459045 (Unicode alternative)
117
+ PHI; // => 1.618033988749895 (Golden ratio)
118
+ φ; // => 1.618033988749895 (Unicode alternative)
119
119
 
120
120
  // Infinity values
121
- POSITIVE_INFINITY // => Infinity
122
- // => Infinity (Unicode alternative)
123
- NEGATIVE_INFINITY // => -Infinity
121
+ POSITIVE_INFINITY; // => Infinity
122
+ ∞; // => Infinity (Unicode alternative)
123
+ NEGATIVE_INFINITY; // => -Infinity
124
124
 
125
125
  // Integer and float limits
126
- MAX_SAFE_INTEGER // => 9007199254740991
127
- MIN_SAFE_INTEGER // => -9007199254740991
128
- MAX_VALUE // => 1.7976931348623157e+308
129
- MIN_VALUE // => 5e-324
130
-
131
- // Not a Number
132
- NaN // => NaN
126
+ MAX_SAFE_INTEGER; // => 9007199254740991
127
+ MIN_SAFE_INTEGER; // => -9007199254740991
128
+ MAX_VALUE; // => 1.7976931348623157e+308
129
+ MIN_VALUE; // => 5e-324
133
130
  ```
134
131
 
135
132
  ## Special Expressions
@@ -144,7 +141,7 @@ let x = 10;
144
141
  // => 10
145
142
 
146
143
  // Variables are immutable
147
- let x = 20; // Error: x is already defined
144
+ // let x = 20; // Error: x is already defined
148
145
 
149
146
  // Shadowing in inner scopes
150
147
  let y = {
@@ -156,29 +153,116 @@ let y = {
156
153
 
157
154
  #### Destructuring
158
155
 
156
+ ##### Basic Object Destructuring
157
+
159
158
  ```lits
160
159
  // Object destructuring
161
160
  let { name, age } = { name: "John", age: 30 };
162
161
  // name => "John", age => 30
162
+ ```
163
163
 
164
- // Array destructuring
165
- let [first, second] = [1, 2, 3, 4];
166
- // first => 1, second => 2
167
-
164
+ ```lits
168
165
  // With default values
169
166
  let { name = "Unknown", age = 0 } = { name: "John" };
170
167
  // name => "John", age => 0
168
+ ```
169
+
170
+ ```lits
171
+ // Renaming with 'as'
172
+ let { name as userName } = { name: "Dave" };
173
+ // userName => "Dave"
174
+ ```
175
+
176
+ ```lits
177
+ // Multiple renames
178
+ let { firstName as name, age as years } = { firstName: "Eve", age: 28 };
179
+ // name => "Eve", years => 28
180
+ ```
181
+
182
+ ##### Advanced Destructuring Patterns
183
+
184
+ ```lits
185
+ // Complex nested destructuring with defaults and renaming
186
+ let {
187
+ name as userName = "Guest",
188
+ profile: {
189
+ age = 0,
190
+ contact: { email as userEmail = "none" }
191
+ },
192
+ settings = { theme: "light" },
193
+ scores as userScores = [],
194
+ ...others
195
+ } = { name: "Sam", profile: { contact: {} }};
196
+ // userName => "Sam", age => 0, userEmail => "none", etc.
197
+ ```
198
+
199
+ ```lits
200
+ // Combining array and object destructuring
201
+ let [{ name }, { age }] = [{ name: "Tina" }, { age: 33 }];
202
+ // name => "Tina", age => 33
203
+ ```
204
+
205
+ ```lits
206
+ // Object with array property destructuring
207
+ let { name, scores: [one, two] } = { name: "Uma", scores: [85, 92] };
208
+ // name => "Uma", one => 85, two => 92
209
+ ```
210
+
211
+ ##### Array Destructuring
171
212
 
172
- // Rest patterns
213
+ ```lits
214
+ // Array destructuring
215
+ let [, , a, b] = [1, 2, 3, 4];
216
+ // a => 3, b => 4
217
+
218
+ // Array destructuring with defaults
219
+ let [one, two = 2] = [1];
220
+ // one => 1, two => 2
221
+
222
+ // Skipping elements
223
+ let [x, , z] = [1, 2, 3];
224
+ // x => 1, z => 3
225
+ ```
226
+
227
+ ##### Rest Patterns
228
+
229
+ ```lits
230
+ // Array rest pattern
173
231
  let [head, ...tail] = [1, 2, 3, 4];
174
232
  // head => 1, tail => [2, 3, 4]
175
233
 
176
- // Destructuring in function parameters
177
- let displayPerson = ({name, age}) ->
178
- name ++ " is " ++ str(age) ++ " years old";
234
+ // Object rest pattern
235
+ let { name, ...otherProps } = { name: "John", age: 30, city: "NYC" };
236
+ // name => "John", otherProps => { age: 30, city: "NYC" }
179
237
 
180
- displayPerson({ name: "John", age: 30 });
181
- // => "John is 30 years old"
238
+ // Empty rest patterns
239
+ let [only, ...empty] = [1];
240
+ // only => 1, empty => []
241
+ ```
242
+
243
+ ##### Function Parameter Destructuring
244
+
245
+ ```lits
246
+ // Basic parameter destructuring
247
+ let greet = ({ name }) -> "Hello, " ++ name;
248
+ greet({ name: "Pat" });
249
+ // => "Hello, Pat"
250
+
251
+ // With defaults in parameters
252
+ let greet2 = ({ name = "friend" }) -> "Hello, " ++ name;
253
+ greet2({});
254
+ // => "Hello, friend"
255
+
256
+ // Nested parameter destructuring
257
+ let processUser = ({ profile: { name, age }}) ->
258
+ name ++ " is " ++ str(age);
259
+ processUser({ profile: { name: "Quinn", age: 29 }});
260
+ // => "Quinn is 29"
261
+
262
+ // Array parameter destructuring
263
+ let processCoords = ([x, y]) -> x + y;
264
+ processCoords([3, 4]);
265
+ // => 7
182
266
  ```
183
267
 
184
268
  ### Functions
@@ -196,10 +280,10 @@ let square = x -> x * x;
196
280
  let constant = () -> 42;
197
281
 
198
282
  // Positional arguments
199
- let add = -> $1 + $2;
283
+ let add-v2 = -> $1 + $2;
200
284
 
201
285
  // Single positional argument
202
- let square = -> $ * $;
286
+ let square-v2 = -> $ * $;
203
287
 
204
288
  // Self-reference for recursion
205
289
  let factorial = n ->
@@ -215,49 +299,76 @@ let factorial = n ->
215
299
  #### If/Unless
216
300
 
217
301
  ```lits
218
- // If expression
302
+ let x = !:random-int(0, 20); // Random number between 0 and 19
303
+
219
304
  if x > 10 then
220
305
  "large"
221
306
  else
222
307
  "small"
223
- end
308
+ end;
224
309
  // => "large" (if x > 10) or "small" (if x <= 10)
225
310
 
226
311
  // If without else returns null
227
- if false then "never" end
312
+ if false then "never" end;
228
313
  // => null
229
314
 
230
315
  // Unless (inverted if)
231
- unless x > 10 then
316
+ let y = !:random-int(0, 20);
317
+ unless y > 10 then
232
318
  "small"
233
319
  else
234
320
  "large"
235
- end
236
- // => "small" (if x <= 10) or "large" (if x > 10)
321
+ end;
322
+ // => "small" (if y <= 10) or "large" (if y > 10)
237
323
  ```
238
324
 
239
325
  #### Cond
240
326
 
241
327
  ```lits
328
+ let x = !:random-int(0, 20); // Random number between 0 and 19
329
+
242
330
  // Multi-branch conditional
243
331
  cond
244
332
  case x < 5 then "small"
245
333
  case x < 10 then "medium"
246
334
  case x < 15 then "large"
247
- end ?? "extra large"
335
+ end ?? "extra large";
248
336
  // Tests conditions sequentially, returns first truthy match
337
+
338
+ // Cond with complex conditions
339
+ let urgent = !:random-int(0, 2) == 1;
340
+ let important = !:random-int(0, 2) == 1;
341
+ let priority = cond
342
+ case urgent && important then "critical"
343
+ case urgent then "high"
344
+ case important then "medium"
345
+ end ?? "low";
249
346
  ```
250
347
 
251
348
  #### Switch
252
349
 
253
350
  ```lits
351
+ let x = !:random-int(0, 3); // Random number between 0 and 2
352
+
254
353
  // Switch on value
255
354
  switch x
256
355
  case 0 then "zero"
257
356
  case 1 then "one"
258
357
  case 2 then "two"
259
- end
358
+ end;
260
359
  // => "zero" (if x = 0), "one" (if x = 1), etc., or null if no match
360
+
361
+ // Switch with multiple cases
362
+ let userInput = "help";
363
+ let exit = -> "exiting";
364
+ let showHelp = -> "showing help";
365
+ let saveData = -> "saving data";
366
+
367
+ switch userInput
368
+ case "quit" then exit()
369
+ case "help" then showHelp()
370
+ case "save" then saveData()
371
+ end;
261
372
  ```
262
373
 
263
374
  ### Loops and Iteration
@@ -266,27 +377,41 @@ end
266
377
 
267
378
  ```lits
268
379
  // Simple iteration
269
- for (x in [1, 2, 3, 4]) -> x * 2
380
+ for (x in [1, 2, 3, 4]) -> x * 2;
270
381
  // => [2, 4, 6, 8]
271
382
 
272
- // With filtering
273
- for (x in [1, 2, 3, 4] when odd?(x)) -> x * 2
383
+ // With filtering (when clause)
384
+ for (x in [1, 2, 3, 4] when odd?(x)) -> x * 2;
274
385
  // => [2, 6]
275
386
 
276
- // With while condition
277
- for (x in [1, 2, 3, 4] while x < 3) -> x * 2
387
+ // With early termination (while clause)
388
+ for (x in [1, 2, 3, 4] while x < 3) -> x * 2;
278
389
  // => [2, 4]
279
390
 
280
- // With let bindings
281
- for (x in [1, 2, 3] let doubled = x * 2) -> doubled + 1
391
+ // With let bindings for intermediate calculations
392
+ for (x in [1, 2, 3] let doubled = x * 2) -> doubled + 1;
282
393
  // => [3, 5, 7]
283
394
 
284
395
  // Multiple iterators
285
- for (x in [1, 2], y in [10, 20]) -> x + y
396
+ for (x in [1, 2], y in [10, 20]) -> x + y;
286
397
  // => [11, 21, 12, 22]
287
398
 
399
+ // Complex for comprehensions with multiple conditions
400
+ for (
401
+ i in range(10)
402
+ let ii = i ^ 2
403
+ while ii < 40
404
+ when ii % 3 == 0,
405
+ j in range(10)
406
+ when j % 2 == 1
407
+ ) -> ii + j;
408
+
409
+ // Using previous bindings in subsequent iterations
410
+ for (x in [1, 2], y in [x, 2 * x]) -> x * y;
411
+ // => [1, 2, 4, 8]
412
+
288
413
  // Object iteration
289
- for ([key, value] in { a: 1, b: 2 }) -> key ++ ":" ++ str(value)
414
+ for (entry in { a: 1, b: 2 } let [key, value] = entry) -> key ++ ":" ++ str(value);
290
415
  // => ["a:1", "b:2"]
291
416
  ```
292
417
 
@@ -308,8 +433,41 @@ loop (n = 5, acc = 1) -> {
308
433
  else
309
434
  recur(n - 1, acc * n)
310
435
  end
311
- }
436
+ };
312
437
  // => 120 (factorial of 5)
438
+
439
+ // Complex loop with multiple variables
440
+ loop (items = [1, 2, 3, 4, 5], sum = 0, cnt = 0) -> {
441
+ if empty?(items) then
442
+ { sum: sum, average: sum / cnt }
443
+ else
444
+ recur(rest(items), sum + first(items), cnt + 1)
445
+ end
446
+ };
447
+ ```
448
+
449
+ ### Recursion with Recur
450
+
451
+ #### Function Recursion
452
+
453
+ ```lits
454
+ // Simple recursive function with recur
455
+ let factorial = (n) -> {
456
+ if n <= 1 then
457
+ 1
458
+ else
459
+ n * recur(n - 1)
460
+ end
461
+ };
462
+
463
+ // Tail-recursive function
464
+ let sumToN = (n, acc = 0) -> {
465
+ if zero?(n) then
466
+ acc
467
+ else
468
+ recur(n - 1, acc + n)
469
+ end
470
+ };
313
471
  ```
314
472
 
315
473
  ### Error Handling
@@ -318,223 +476,207 @@ loop (n = 5, acc = 1) -> {
318
476
 
319
477
  ```lits
320
478
  // Basic try/catch
479
+ let riskyOperation = () -> throw("Something went wrong");
321
480
  try
322
481
  riskyOperation()
323
482
  catch
324
483
  "Something went wrong"
325
- end
484
+ end;
326
485
 
327
486
  // With error binding
328
487
  try
329
488
  riskyOperation()
330
489
  catch (error)
331
490
  "Error: " ++ error.message
332
- end
491
+ end;
492
+
493
+ // Try-catch for graceful degradation
494
+ let parseData = () -> { value: 42 };
495
+ let process = (val) -> val * 2;
496
+ try
497
+ let { value } = parseData();
498
+ process(value);
499
+ catch
500
+ "Using default value"
501
+ end;
333
502
  ```
334
503
 
335
504
  #### Throw
336
505
 
337
506
  ```lits
338
507
  // Throwing errors
339
- throw("Custom error message")
508
+ try
509
+ throw("Custom error message")
510
+ catch
511
+ "Caught an error"
512
+ end;
340
513
 
341
- // In context
514
+ // Custom error messages in functions
342
515
  let divide = (a, b) ->
343
516
  if zero?(b) then
344
- throw("Division by zero")
517
+ throw("Cannot divide by zero")
345
518
  else
346
519
  a / b
347
520
  end;
348
- ```
349
521
 
350
- ### Logical Operators
351
-
352
- #### And/Or
353
-
354
- ```lits
355
- // Logical AND (short-circuit)
356
- true && "second value" // => "second value"
357
- false && "never reached" // => false
358
-
359
- // Logical OR (short-circuit)
360
- false || "default value" // => "default value"
361
- true || "never reached" // => true
362
-
363
- // Multiple arguments
364
- &&(true, true, "all true") // => "all true"
365
- ||(false, false, "found") // => "found"
522
+ // Conditional error throwing
523
+ let validateAge = (age) ->
524
+ cond
525
+ case age < 0 then throw("Age cannot be negative")
526
+ case age > 150 then throw("Age seems unrealistic")
527
+ case true then age
528
+ end;
366
529
  ```
367
530
 
368
- #### Null Coalescing
531
+ ### Block Expressions
369
532
 
370
533
  ```lits
371
- // Null coalescing operator
372
- null ?? "default" // => "default"
373
- undefined ?? "default" // => "default"
374
- 0 ?? "default" // => 0 (only null/undefined are coalesced)
375
- false ?? "default" // => false
376
- "" ?? "default" // => ""
377
- ```
534
+ // Block for grouping expressions
535
+ let computeX = () -> 5;
536
+ let computeY = () -> 10;
537
+ let processResult = (z) -> z * 2;
538
+
539
+ let result = {
540
+ let x = computeX();
541
+ let y = computeY();
542
+ let z = x * y;
543
+ processResult(z)
544
+ };
378
545
 
379
- ### Blocks
546
+ // Block with side effects
547
+ let loadData = () -> [1, 2, 3];
548
+ let processData = (data) -> data map -> $ * 2;
380
549
 
381
- ```lits
382
- // Block expressions
383
550
  {
384
- let a = 1 + 2 + 3;
385
- let b = x -> x * x;
386
- b(a)
387
- }
388
- // => 36 (returns value of last expression)
551
+ write!("Starting process...");
552
+ let data = loadData();
553
+ let processed = processData(data);
554
+ write!("Process completed");
555
+ processed
556
+ };
389
557
  ```
390
558
 
391
- ### Arrays and Objects
559
+ ### Array and Object Spread
392
560
 
393
- #### Array Construction
561
+ #### Array Spread
394
562
 
395
563
  ```lits
396
- // Array literal
397
- [1, 2, 3, 4]
398
-
399
- // Array function
400
- array(1, 2, 3, 4)
401
-
402
- // With spread
403
- [1, 2, ...[3, 4, 5], 6]
564
+ // Spread in array literals
565
+ let combined = [1, 2, ...[3, 4, 5], 6];
404
566
  // => [1, 2, 3, 4, 5, 6]
567
+
568
+ // Multiple spreads
569
+ let start = [1, 2];
570
+ let middle = [3, 4];
571
+ let stop = [5, 6];
572
+ let result = [...start, ...middle, ...stop];
405
573
  ```
406
574
 
407
- #### Object Construction
575
+ #### Object Spread
408
576
 
409
577
  ```lits
410
- // Object literal
411
- { name: "John", age: 30 }
412
-
413
- // Object function
414
- object("name", "John", "age", 30)
415
-
416
- // With spread
417
- let defaults = { type: "Person", active: true };
418
- {
419
- ...defaults,
578
+ // Object spread for merging
579
+ let person = {
420
580
  name: "John",
421
581
  age: 30
422
- }
423
- // => { type: "Person", active: true, name: "John", age: 30 }
424
- ```
425
-
426
- ### Recursion
582
+ };
427
583
 
428
- #### Recur
584
+ let employee = {
585
+ ...person,
586
+ id: "E123",
587
+ department: "Engineering"
588
+ };
589
+ // => { name: "John", age: 30, id: "E123", department: "Engineering" }
429
590
 
430
- ```lits
431
- // Tail recursion with recur
432
- let countdown = n -> {
433
- write!(n);
434
- if pos?(n) then
435
- recur(n - 1)
436
- end
591
+ // Spread with override
592
+ let defaults = {
593
+ name: "Default Name",
594
+ theme: "light",
595
+ active: true
437
596
  };
438
597
 
439
- countdown(3)
440
- // Prints: 3 2 1 0
598
+ let updated = {
599
+ ...defaults,
600
+ name: "Custom Name" // Override defaults.name
601
+ };
441
602
  ```
442
603
 
443
- ## Operators and Functions
444
-
445
- ### Algebraic Notation
604
+ ### Logical Operators
446
605
 
447
- All functions that take two parameters can be used as operators:
606
+ #### And/Or
448
607
 
449
608
  ```lits
450
- // As a function
451
- max(5, 10) // => 10
609
+ // Logical AND (short-circuit)
610
+ true && "second value"; // => "second value"
611
+ false && "never reached"; // => false
612
+
613
+ // Logical OR (short-circuit)
614
+ false || "default value"; // => "default value"
615
+ true || "never reached"; // => true
452
616
 
453
- // As an operator
454
- 5 max 10 // => 10
617
+ // Multiple arguments
618
+ &&(true, true, "all true"); // => "all true"
619
+ ||(false, false, "found"); // => "found"
455
620
  ```
456
621
 
457
- All operators can be used as functions:
622
+ #### Null Coalescing
458
623
 
459
624
  ```lits
460
- // As an operator
461
- 5 + 3 // => 8
462
-
463
- // As a function
464
- +(5, 3) // => 8
625
+ // Null coalescing operator
626
+ null ?? "default"; // => "default"
627
+ undefined-var ?? "default"; // => "default"
628
+ 0 ?? "default"; // => 0 (only null/undefined are coalesced)
629
+ false ?? "default"; // => false
630
+ "" ?? "default"; // => ""
631
+ ```
465
632
 
466
- // Partial application with underscore placeholder
467
- let add5 = +(5, _);
468
- add5(3) // => 8
633
+ ### Ternary Operator
469
634
 
470
- // Multiple placeholders
471
- let subtractAndDivide = /(-(_, _), 2);
472
- subtractAndDivide(10, 3) // => 3.5 (10 - 3 = 7, then 7 / 2 = 3.5)
635
+ ```lits
636
+ // Conditional expression
637
+ let age = !:random-int(10, 60);
638
+ let result = age >= 18 ? "adult" : "minor";
473
639
 
474
- // Single placeholder in different positions
475
- let subtract = -(_, 2);
476
- subtract(10) // => 8
640
+ // Nested ternary
641
+ let score = !:random-int(0, 100);
642
+ let category = score >= 90 ? "A" : score >= 80 ? "B" : "C";
477
643
 
478
- let divide = /(10, _);
479
- divide(2) // => 5
644
+ // With complex expressions
645
+ let isLoggedIn = () -> true;
646
+ let hasPermission = () -> true;
647
+ let status = isLoggedIn() && hasPermission() ? "authorized" : "unauthorized";
480
648
  ```
481
649
 
482
- ### Parameter Order
650
+ ## Operators and Precedence
483
651
 
484
- Lits favors subject-first parameter order for better operator chaining:
652
+ Lits follows a clear operator precedence hierarchy. Understanding precedence helps you write expressions that behave as expected:
485
653
 
486
- ```lits
487
- // Function style
488
- filter([1, 2, 3, 4], odd?) // => [1, 3]
654
+ ### Precedence Table (Highest to Lowest)
489
655
 
490
- // Operator style (more readable)
491
- [1, 2, 3, 4] filter odd? // => [1, 3]
656
+ 1. **Function calls** - `fn(args)`
657
+ 2. **Array/Object access** - `arr[index]`, `obj.property`
658
+ 3. **Unary operators** - `not`, `!`, `-` (negation)
659
+ 4. **Exponentiation** - `^` (right-associative)
660
+ 5. **Multiplication, Division, Modulo** - `*`, `/`, `%`
661
+ 6. **Addition, Subtraction** - `+`, `-`
662
+ 7. **String concatenation** - `++`
663
+ 8. **Comparison operators** - `<`, `>`, `<=`, `>=`
664
+ 9. **Equality operators** - `==`, `!=`, `identical?`
665
+ 10. **Logical AND** - `&&`
666
+ 11. **Logical OR** - `||`
667
+ 12. **Null coalescing** - `??`
668
+ 13. **Ternary conditional** - `condition ? true-value : false-value`
492
669
 
493
- // Chaining
494
- [1, 2, 3, 4, 5, 6]
495
- filter odd?
496
- map square
497
- reduce +
498
- // => 35
499
- ```
500
-
501
- ### Pipe Operator
502
-
503
- The pipe operator `|>` passes the result of the left expression as the first argument to the right function:
670
+ ### Examples
504
671
 
505
672
  ```lits
506
- // Without pipe operator
507
- reduce(map(filter([1, 2, 3, 4, 5, 6], odd?), square), +)
673
+ // Comparison and logical operators
674
+ 5 > 3 && 2 < 4; // => true
675
+ 5 > 3 || 2 > 4; // => true
508
676
 
509
- // With pipe operator (much more readable)
510
- [1, 2, 3, 4, 5, 6]
511
- |> filter(_, odd?)
512
- |> map(_, square)
513
- |> reduce(_, +)
514
- // => 35
515
-
516
- // Simple transformations
517
- "hello world"
518
- |> upper-case
519
- |> split(_, " ")
520
- |> reverse
521
- |> join(_, "-")
522
- // => "WORLD-HELLO"
523
-
524
- // Mathematical operations
525
- 10
526
- |> +(_, 5)
527
- |> *(_, 2)
528
- |> /(_, 3)
529
- // => 10 (10 + 5 = 15, 15 * 2 = 30, 30 / 3 = 10)
530
-
531
- // Data processing pipeline
532
- { numbers: [1, 2, 3, 4, 5], multiplier: 3 }
533
- |> get(_, "numbers")
534
- |> filter(_, even?)
535
- |> map(_, *(_, 3))
536
- |> reduce(_, +)
537
- // => 18 (even numbers [2, 4] -> [6, 12] -> sum = 18)
677
+ // Ternary has low precedence
678
+ let x = !:random-int(0, 10);
679
+ x + 3 > 4 ? 1 : 0; // => (x + 3) > 4 ? 1 : 0
538
680
  ```
539
681
 
540
682
  ## Built-in Functions
@@ -557,7 +699,7 @@ For a complete reference of all available functions with examples, visit the [Li
557
699
 
558
700
  ```lits
559
701
  // Export variables and functions
560
- export let PI = 3.14159;
702
+ export let pi = 3.14159;
561
703
  export let square = x -> x * x;
562
704
 
563
705
  // Exported values become available to other modules
@@ -568,12 +710,7 @@ export let square = x -> x * x;
568
710
  ### Factorial
569
711
 
570
712
  ```lits
571
- let factorial = n ->
572
- if n <= 1 then
573
- 1
574
- else
575
- n * self(n - 1)
576
- end;
713
+ let factorial = n -> n <= 1 ? 1 : n * self(n - 1);
577
714
 
578
715
  factorial(5) // => 120
579
716
  ```
@@ -585,110 +722,78 @@ let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
585
722
 
586
723
  // Get even numbers squared
587
724
  let evenSquares = numbers
588
- filter even?
589
- map square;
725
+ |> filter(_, even?)
726
+ |> map(_, -> $ * $);
590
727
  // => [4, 16, 36, 64, 100]
591
728
 
592
729
  // Sum of odd numbers
593
730
  let oddSum = numbers
594
- filter odd?
595
- reduce +;
731
+ |> filter(_, odd?)
732
+ |> reduce(_, +, 0);
596
733
  // => 25
597
734
  ```
598
735
 
599
- ### Object Manipulation
600
-
601
- ```lits
602
- let person = { name: "John", age: 30, city: "New York" };
603
-
604
- // Update age
605
- let older = assoc(person, "age", 31);
606
-
607
- // Add new field
608
- let withJob = assoc(older, "job", "Developer");
609
-
610
- // Using pipe operator for chaining
611
- let updated = person
612
- |> assoc(_, "age", 31)
613
- |> assoc(_, "job", "Developer");
614
- ```
615
-
616
- ### Pattern Matching Examples
617
-
618
- #### Switch (for matching against a single value)
736
+ ### String Processing
619
737
 
620
738
  ```lits
621
- let gradeToLetter = grade ->
622
- switch grade
623
- case 90 then "A"
624
- case 80 then "B"
625
- case 70 then "C"
626
- case 60 then "D"
627
- end ?? "F";
739
+ let text = "Hello, World! How are you today?";
628
740
 
629
- gradeToLetter(80) // => "B"
630
- gradeToLetter(55) // => "F"
741
+ // Word count
742
+ let wordCount = text
743
+ |> split(_, #"\s+")
744
+ |> count(_);
745
+ // => 6
631
746
 
632
- // HTTP status code handling
633
- let statusMessage = code ->
634
- switch code
635
- case 200 then "OK"
636
- case 404 then "Not Found"
637
- case 500 then "Internal Server Error"
638
- end ?? "Unknown Status";
747
+ // Uppercase words longer than 4 characters
748
+ let longWords = text
749
+ |> split(_, #"\s+")
750
+ |> filter(_, -> count($) > 4)
751
+ |> map(_, upper-case);
752
+ // => ["HELLO,", "WORLD!", "TODAY?"]
639
753
  ```
640
754
 
641
- #### Cond (for testing different conditions)
755
+ ### Data Transformation
642
756
 
643
757
  ```lits
644
- let describe = x ->
645
- cond
646
- case null?(x) then "nothing"
647
- case number?(x) then "a number: " ++ str(x)
648
- case string?(x) then "text: " ++ x
649
- case array?(x) then "list of " ++ str(count(x)) ++ " items"
650
- end ?? "unknown type";
651
-
652
- describe(42) // => "a number: 42"
653
- describe([1,2,3]) // => "list of 3 items"
654
-
655
- // Grade ranges
656
- let gradeToLetter = score ->
657
- cond
658
- case score >= 90 then "A"
659
- case score >= 80 then "B"
660
- case score >= 70 then "C"
661
- case score >= 60 then "D"
662
- end ?? "F";
663
-
664
- gradeToLetter(85) // => "B"
665
- gradeToLetter(55) // => "F"
758
+ let users = [
759
+ { name: "Alice", age: 30, department: "Engineering" },
760
+ { name: "Bob", age: 25, department: "Marketing" },
761
+ { name: "Charlie", age: 35, department: "Engineering" }
762
+ ];
763
+
764
+ // Group by department and get average age
765
+ let grouped = users |> group-by(_, "department");
766
+ let departmentAges = grouped
767
+ |> entries(_)
768
+ |> map(_, ([dept, people]) -> {
769
+ let ages = people |> map(_, "age");
770
+ let total = ages |> reduce(_, +, 0);
771
+ [dept, total / count(ages)]
772
+ })
773
+ |> (pairs -> zipmap(map(pairs, 0), map(pairs, 1)));
774
+ // => { "Engineering": 32.5, "Marketing": 25 }
666
775
  ```
667
776
 
668
777
  ## JavaScript Interoperability
669
778
 
670
- Lits provides a comprehensive JavaScript API for embedding and integration:
779
+ ### Using Lits in JavaScript
671
780
 
672
781
  ```javascript
673
- import { Lits } from 'lits';
782
+ import { Lits } from '@mojir/lits';
674
783
 
675
- // Create a Lits instance
676
784
  const lits = new Lits();
677
785
 
678
- // Run Lits code
679
- const result = lits.run('+(5, 3)');
680
- console.log(result); // 8
786
+ // Basic usage
787
+ const result1 = lits.run('+(1, 2, 3)');
788
+ console.log(result1); // 6
681
789
 
682
- // Pass JavaScript values to Lits
790
+ // Provide JavaScript values
683
791
  const result2 = lits.run('name ++ " is " ++ str(age)', {
684
- values: {
685
- name: "John",
686
- age: 30
687
- }
792
+ values: { name: 'John', age: 30 }
688
793
  });
689
794
  console.log(result2); // "John is 30"
690
795
 
691
- // Expose JavaScript functions to Lits
796
+ // Expose JavaScript functions
692
797
  const result3 = lits.run('myAlert("Hello from Lits!")', {
693
798
  jsFunctions: {
694
799
  myAlert: {