@mojir/dvala 0.0.30 → 0.0.32

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.
Files changed (3) hide show
  1. package/README.md +145 -218
  2. package/dist/cli/cli.js +5831 -5927
  3. package/package.json +1 -6
package/README.md CHANGED
@@ -41,7 +41,7 @@ $ dvala
41
41
 
42
42
  # Evaluate Dvala code directly
43
43
  $ dvala eval "5 + 3"
44
- $ dvala eval "[1, 2, 3, 4] filter odd? map inc"
44
+ $ dvala eval "[1, 2, 3, 4] filter isOdd map inc"
45
45
 
46
46
  # Run a Dvala file
47
47
  $ dvala run script.dvala
@@ -184,7 +184,7 @@ rest(numbers); // => [2, 3, 4, 5]
184
184
 
185
185
  // Functional array operations
186
186
  numbers map -> $ * 2; // => [2, 4, 6, 8, 10]
187
- numbers filter odd?; // => [1, 3, 5]
187
+ numbers filter isOdd; // => [1, 3, 5]
188
188
  ```
189
189
 
190
190
  #### Vectors (Number Arrays)
@@ -194,7 +194,7 @@ A vector is simply a non-empty array containing only numbers. The `vec` module p
194
194
  ```dvala
195
195
  // Import vector and linear algebra modules
196
196
  let vec = import(vector);
197
- let lin = import(linear-algebra);
197
+ let lin = import(linearAlgebra);
198
198
 
199
199
  // Vectors are just number arrays
200
200
  [1, 2, 3, 4, 5]; // This is a vector
@@ -210,30 +210,30 @@ repeat(3.14, 4); // => [3.14, 3.14, 3.14, 3.14]
210
210
 
211
211
  // Vector mathematical operations (use lin module for vector math)
212
212
  lin.dot([1, 2, 3], [4, 5, 6]); // => 32 (dot product)
213
- lin.euclidean-norm([3, 4]); // => 5.0 (Euclidean norm/magnitude)
214
- lin.normalize-l2([3, 4]); // => [0.6, 0.8] (unit vector)
215
- lin.euclidean-distance([0, 0], [3, 4]); // => 5.0 (Euclidean distance)
216
-
217
- // Vector statistical operations (sum, mean, median, prod are core built-ins)
218
- sum([1, 2, 3, 4]); // => 10
219
- mean([1, 2, 3, 4]); // => 2.5
220
- median([1, 2, 3, 4, 5]); // => 3
213
+ lin.euclideanNorm([3, 4]); // => 5.0 (Euclidean norm/magnitude)
214
+ lin.normalizeL2([3, 4]); // => [0.6, 0.8] (unit vector)
215
+ lin.euclideanDistance([0, 0], [3, 4]); // => 5.0 (Euclidean distance)
216
+
217
+ // Vector statistical operations (in the vector module)
218
+ vec.sum([1, 2, 3, 4]); // => 10
219
+ vec.mean([1, 2, 3, 4]); // => 2.5
220
+ vec.median([1, 2, 3, 4, 5]); // => 3
221
221
  vec.stdev([1, 2, 3, 4]); // => 1.29... (standard deviation)
222
222
  vec.variance([1, 2, 3, 4]); // => 1.67... (variance)
223
223
 
224
224
  // Vector analysis (min and max are core built-ins)
225
225
  min([3, 1, 4, 1, 5]); // => 1
226
226
  max([3, 1, 4, 1, 5]); // => 5
227
- vec.min-index([3, 1, 4]); // => 1 (index of minimum)
228
- vec.max-index([3, 1, 4]); // => 2 (index of maximum)
227
+ vec.minIndex([3, 1, 4]); // => 1 (index of minimum)
228
+ vec.maxIndex([3, 1, 4]); // => 2 (index of maximum)
229
229
 
230
230
  // Cumulative operations
231
231
  vec.cumsum([1, 2, 3, 4]); // => [1, 3, 6, 10]
232
232
  vec.cumprod([1, 2, 3, 4]); // => [1, 2, 6, 24]
233
233
 
234
234
  // Vector predicates
235
- vec.increasing?([1, 1, 2, 3, 4]); // => true
236
- vec.strictly-increasing?([1, 1, 2, 3, 4]); // => false
235
+ vec.isIncreasing([1, 1, 2, 3, 4]); // => true
236
+ vec.isStrictlyIncreasing([1, 1, 2, 3, 4]); // => false
237
237
 
238
238
  // Structural equality works with all vectors
239
239
  [1, 2, 3] == [1, 2, 3]; // => true
@@ -270,20 +270,20 @@ mat.vandermonde([1, 2, 3]); // => Vandermonde matrix from vector
270
270
  mat.band(4, 1, 1); // => 4x4 band matrix
271
271
 
272
272
  // Matrix properties and predicates
273
- mat.symmetric?([[1, 2], [2, 1]]); // => true
274
- mat.invertible?([[1, 2], [3, 4]]); // => true
275
- mat.square?([[1, 2], [3, 4]]); // => true
276
- mat.diagonal?([[1, 0], [0, 2]]); // => true
277
- mat.identity?([[1, 0], [0, 1]]); // => true
273
+ mat.isSymmetric([[1, 2], [2, 1]]); // => true
274
+ mat.isInvertible([[1, 2], [3, 4]]); // => true
275
+ mat.isSquare([[1, 2], [3, 4]]); // => true
276
+ mat.isDiagonal([[1, 0], [0, 2]]); // => true
277
+ mat.isIdentity([[1, 0], [0, 1]]); // => true
278
278
 
279
279
  // Advanced matrix operations
280
280
  mat.adj(matrixA); // => [[4, -2], [-3, 1]] (adjugate)
281
281
  mat.cofactor(matrixA); // => cofactor matrix
282
282
  mat.minor(matrixA, 0, 1); // => minor by removing row 0, col 1
283
- mat.frobenius-norm(matrixA); // => Frobenius norm
284
- mat.one-norm(matrixA); // => 1-norm (max column sum)
285
- mat.inf-norm(matrixA); // => infinity norm (max row sum)
286
- mat.max-norm(matrixA); // => max norm (largest absolute element)
283
+ mat.frobeniusNorm(matrixA); // => Frobenius norm
284
+ mat.oneNorm(matrixA); // => 1-norm (max column sum)
285
+ mat.infNorm(matrixA); // => infinity norm (max row sum)
286
+ mat.maxNorm(matrixA); // => max norm (largest absolute element)
287
287
 
288
288
  // Matrix analysis
289
289
  mat.rank(matrixA); // => matrix rank
@@ -320,33 +320,33 @@ Dvala provides predicate functions to check data types at runtime:
320
320
 
321
321
  ```dvala
322
322
  // Basic type predicates
323
- number?(42); // => true
324
- string?("hello"); // => true
325
- boolean?(true); // => true
326
- function?(x -> x * 2); // => true
327
- regexp?(#"[a-z]+"); // => true
328
- array?([1, 2, 3]); // => true
329
- object?({name: "Alice"}); // => true
330
- null?(null); // => true
323
+ isNumber(42); // => true
324
+ isString("hello"); // => true
325
+ isBoolean(true); // => true
326
+ isFunction(x -> x * 2); // => true
327
+ isRegexp(#"[a-z]+"); // => true
328
+ isArray([1, 2, 3]); // => true
329
+ isObject({name: "Alice"}); // => true
330
+ isNull(null); // => true
331
331
 
332
332
  // Specialized array predicates
333
- vector?([1, 2, 3]); // => true (non-empty number array)
334
- vector?([1, "hello", 3]); // => false (mixed types)
335
- vector?([]); // => false (empty)
333
+ isVector([1, 2, 3]); // => true (non-empty number array)
334
+ isVector([1, "hello", 3]); // => false (mixed types)
335
+ isVector([]); // => false (empty)
336
336
 
337
- matrix?([[1, 2], [3, 4]]); // => true (2D number array, consistent rows)
338
- matrix?([[1, 2], [3]]); // => false (inconsistent row lengths)
339
- matrix?([[]]); // => false (contains empty row)
337
+ isMatrix([[1, 2], [3, 4]]); // => true (2D number array, consistent rows)
338
+ isMatrix([[1, 2], [3]]); // => false (inconsistent row lengths)
339
+ isMatrix([[]]); // => false (contains empty row)
340
340
 
341
341
  // Collection predicates
342
- sequence?([1, 2, 3]); // => true (sequences: strings and arrays)
343
- sequence?("hello"); // => true
344
- sequence?({a: 1}); // => false
342
+ isSequence([1, 2, 3]); // => true (sequences: strings and arrays)
343
+ isSequence("hello"); // => true
344
+ isSequence({a: 1}); // => false
345
345
 
346
- collection?([1, 2, 3]); // => true (collections: strings, arrays, objects)
347
- collection?("hello"); // => true
348
- collection?({a: 1}); // => true
349
- collection?(42); // => false
346
+ isCollection([1, 2, 3]); // => true (collections: strings, arrays, objects)
347
+ isCollection("hello"); // => true
348
+ isCollection({a: 1}); // => true
349
+ isCollection(42); // => false
350
350
  ```
351
351
 
352
352
  #### Type Hierarchy
@@ -356,19 +356,19 @@ The type predicates follow a logical hierarchy:
356
356
  ```dvala
357
357
  // If something is a matrix, it's also a vector and an array
358
358
  let mat = [[1, 2], [3, 4]];
359
- matrix?(mat); // => true
360
- vector?(mat); // => true (matrix is a special vector)
361
- array?(mat); // => true (vector is a special array)
359
+ isMatrix(mat); // => true
360
+ isVector(mat); // => true (matrix is a special vector)
361
+ isArray(mat); // => true (vector is a special array)
362
362
 
363
363
  // If something is a vector, it's also an array
364
364
  let vec = [1, 2, 3];
365
- vector?(vec); // => true
366
- array?(vec); // => true
365
+ isVector(vec); // => true
366
+ isArray(vec); // => true
367
367
 
368
368
  // But not all arrays are vectors
369
369
  let arr = [1, "hello", 3];
370
- array?(arr); // => true
371
- vector?(arr); // => false (contains non-numbers)
370
+ isArray(arr); // => true
371
+ isVector(arr); // => false (contains non-numbers)
372
372
  ```
373
373
 
374
374
  Each data type is immutable by design - operations return new values rather than modifying existing ones, ensuring predictable behavior and easier reasoning about code.
@@ -379,15 +379,11 @@ Dvala provides predefined mathematical constants:
379
379
 
380
380
  ```dvala
381
381
  PI; // => 3.141592653589793
382
- π; // => 3.141592653589793 (Unicode alternative)
383
382
  E; // => 2.718281828459045 (Euler's number)
384
- ε; // => 2.718281828459045 (Unicode alternative)
385
383
  PHI; // => 1.618033988749895 (Golden ratio)
386
- φ; // => 1.618033988749895 (Unicode alternative)
387
384
 
388
385
  // Infinity values
389
386
  POSITIVE_INFINITY; // => Infinity
390
- ∞; // => Infinity (Unicode alternative)
391
387
  NEGATIVE_INFINITY; // => -Infinity
392
388
 
393
389
  // Integer and float limits
@@ -562,10 +558,10 @@ let square = x -> x * x;
562
558
  let constant = () -> 42;
563
559
 
564
560
  // Positional arguments
565
- let add-v2 = -> $1 + $2;
561
+ let addV2 = -> $ + $2;
566
562
 
567
563
  // Single positional argument
568
- let square-v2 = -> $ * $;
564
+ let squareV2 = -> $ * $;
569
565
 
570
566
  // Self-reference for recursion
571
567
  let factorial = n ->
@@ -578,7 +574,7 @@ let factorial = n ->
578
574
 
579
575
  ### Control Flow
580
576
 
581
- #### If/Unless
577
+ #### If
582
578
 
583
579
  ```dvala
584
580
  let x = 15; // Fixed value for compilation
@@ -594,9 +590,9 @@ end;
594
590
  if false then "never" end;
595
591
  // => null
596
592
 
597
- // Unless (inverted if)
593
+ // Negated condition
598
594
  let y = 8;
599
- unless y > 10 then
595
+ if not(y > 10) then
600
596
  "small"
601
597
  else
602
598
  "large"
@@ -604,28 +600,26 @@ end;
604
600
  // => "small"
605
601
  ```
606
602
 
607
- #### Cond
603
+ #### If / Else If
608
604
 
609
605
  ```dvala
610
606
  let x = 12;
611
607
 
612
608
  // Multi-branch conditional
613
- cond
614
- case x < 5 then "small"
615
- case x < 10 then "medium"
616
- case x < 15 then "large"
617
- case true then "extra large" // default case
609
+ if x < 5 then "small"
610
+ else if x < 10 then "medium"
611
+ else if x < 15 then "large"
612
+ else "extra large" // default case
618
613
  end;
619
614
  // => "large"
620
615
 
621
- // Cond with complex conditions
616
+ // If/else if with complex conditions
622
617
  let urgent = true;
623
618
  let important = false;
624
- let priority = cond
625
- case urgent && important then "critical"
626
- case urgent then "high"
627
- case important then "medium"
628
- case true then "low"
619
+ let priority = if urgent && important then "critical"
620
+ else if urgent then "high"
621
+ else if important then "medium"
622
+ else "low"
629
623
  end;
630
624
  // => "high"
631
625
  ```
@@ -667,7 +661,7 @@ for (x in [1, 2, 3, 4]) -> x * 2;
667
661
  // => [2, 4, 6, 8]
668
662
 
669
663
  // With filtering (when clause)
670
- for (x in [1, 2, 3, 4] when odd?(x)) -> x * 2;
664
+ for (x in [1, 2, 3, 4] when isOdd(x)) -> x * 2;
671
665
  // => [2, 6]
672
666
 
673
667
  // With early termination (while clause)
@@ -701,12 +695,12 @@ for (entry in { a: 1, b: 2 } let [key, value] = entry) -> key ++ ":" ++ str(valu
701
695
  // => ["a:1", "b:2"]
702
696
  ```
703
697
 
704
- #### Doseq (Side Effects)
698
+ #### For with Side Effects
705
699
 
706
700
  ```dvala
707
- // For side effects only (returns null)
708
- doseq (x in [1, 2, 3]) -> perform(effect(dvala.io.println), x)
709
- // Prints: 1 2 3, returns null
701
+ // For can also be used for side effects
702
+ for (x in [1, 2, 3]) -> perform(@dvala.io.print, x)
703
+ // Prints: 1 2 3, returns [null, null, null]
710
704
  ```
711
705
 
712
706
  #### Loop (Tail Recursion)
@@ -714,7 +708,7 @@ doseq (x in [1, 2, 3]) -> perform(effect(dvala.io.println), x)
714
708
  ```dvala
715
709
  // Loop with recur for tail recursion
716
710
  loop (n = 5, acc = 1) -> do
717
- if zero?(n) then
711
+ if isZero(n) then
718
712
  acc
719
713
  else
720
714
  recur(n - 1, acc * n)
@@ -724,7 +718,7 @@ end;
724
718
 
725
719
  // Complex loop with multiple variables
726
720
  loop (items = [1, 2, 3, 4, 5], acc = 0, cnt = 0) -> do
727
- if empty?(items) then
721
+ if isEmpty(items) then
728
722
  { sum: acc, average: acc / cnt }
729
723
  else
730
724
  recur(rest(items), acc + first(items), cnt + 1)
@@ -748,7 +742,7 @@ end;
748
742
 
749
743
  // Tail-recursive function
750
744
  let sumToN = (n, acc = 0) -> do
751
- if zero?(n) then
745
+ if isZero(n) then
752
746
  acc
753
747
  else
754
748
  recur(n - 1, acc + n)
@@ -758,59 +752,66 @@ end;
758
752
 
759
753
  ### Error Handling
760
754
 
761
- #### Do/With Effect Handlers
755
+ #### Handle/With Effect Handlers
762
756
 
763
757
  ```dvala
764
- // Basic error handling with do/with
765
- let riskyOperation = () -> perform(effect(dvala.error), "Something went wrong");
766
- do
758
+ // Basic error handling with handle/with
759
+ let riskyOperation = () -> perform(@dvala.error, "Something went wrong");
760
+ handle
767
761
  riskyOperation()
768
- with
769
- case effect(dvala.error) then (args) -> "Something went wrong"
770
- end;
762
+ with [(arg, eff, nxt) ->
763
+ if eff == @dvala.error then "Something went wrong"
764
+ else nxt(eff, arg)
765
+ end
766
+ ] end;
771
767
 
772
768
  // With error message binding
773
- do
769
+ handle
774
770
  riskyOperation()
775
- with
776
- case effect(dvala.error) then ([msg]) -> "Error: " ++ msg
777
- end;
771
+ with [(arg, eff, nxt) ->
772
+ if eff == @dvala.error then "Error: " ++ arg
773
+ else nxt(eff, arg)
774
+ end
775
+ ] end;
778
776
 
779
777
  // Error handling for graceful degradation
780
778
  let parseData = () -> { value: 42 };
781
779
  let process = (val) -> val * 2;
782
- do
780
+ handle
783
781
  let { value } = parseData();
784
782
  process(value)
785
- with
786
- case effect(dvala.error) then (args) -> "Using default value"
787
- end;
783
+ with [(arg, eff, nxt) ->
784
+ if eff == @dvala.error then "Using default value"
785
+ else nxt(eff, arg)
786
+ end
787
+ ] end;
788
788
  ```
789
789
 
790
790
  #### Raising Errors
791
791
 
792
792
  ```dvala
793
793
  // Raising errors
794
- do
795
- perform(effect(dvala.error), "Custom error message")
796
- with
797
- case effect(dvala.error) then (args) -> "Caught an error"
798
- end;
794
+ handle
795
+ perform(@dvala.error, "Custom error message")
796
+ with [(arg, eff, nxt) ->
797
+ if eff == @dvala.error then "Caught an error"
798
+ else nxt(eff, arg)
799
+ end
800
+ ] end;
799
801
 
800
802
  // Custom error messages in functions
801
803
  let divide = (a, b) ->
802
- if zero?(b) then
803
- perform(effect(dvala.error), "Cannot divide by zero")
804
+ if isZero(b) then
805
+ perform(@dvala.error, "Cannot divide by zero")
804
806
  else
805
807
  a / b
806
808
  end;
807
809
 
808
810
  // Conditional error raising
809
811
  let validateAge = (age) ->
810
- cond
811
- case age < 0 then perform(effect(dvala.error), "Age cannot be negative")
812
- case age > 150 then perform(effect(dvala.error), "Age seems unrealistic")
813
- case true then age
812
+ if age < 0 then perform(@dvala.error, "Age cannot be negative")
813
+ else if age > 150 then perform(@dvala.error, "Age seems unrealistic")
814
+ else age
814
815
  end;
815
816
  ```
816
817
 
@@ -834,10 +835,10 @@ let loadData = () -> [1, 2, 3];
834
835
  let processData = (data) -> data map -> $ * 2;
835
836
 
836
837
  do
837
- perform(effect(dvala.io.println), "Starting process...");
838
+ perform(@dvala.io.print, "Starting process...");
838
839
  let data = loadData();
839
840
  let processed = processData(data);
840
- perform(effect(dvala.io.println), "Process completed");
841
+ perform(@dvala.io.print, "Process completed");
841
842
  processed
842
843
  end
843
844
  ```
@@ -854,8 +855,8 @@ end
854
855
  array(1, 2, 3, 4);
855
856
 
856
857
  // With spread
857
- let small-set = [3, 4, 5];
858
- [1, 2, ...small-set, 6];
858
+ let smallSet = [3, 4, 5];
859
+ [1, 2, ...smallSet, 6];
859
860
  // => [1, 2, 3, 4, 5, 6]
860
861
  ```
861
862
 
@@ -958,134 +959,61 @@ true || "never reached"; // => true
958
959
  ```dvala
959
960
  // Null coalescing operator
960
961
  null ?? "default"; // => "default"
961
- 0 ?? "default"; // => 0 (only null/undefined are coalesced)
962
+ 0 ?? "default"; // => 0 (only null is coalesced)
962
963
  false ?? "default"; // => false
963
964
  "" ?? "default"; // => ""
964
965
  ```
965
966
 
966
- ### Ternary Operator
967
+ ### Conditional Expression
967
968
 
968
969
  ```dvala
969
- // Conditional expression
970
+ // Conditional expression (if/then/else/end)
970
971
  let age = 25;
971
- let result = age >= 18 ? "adult" : "minor";
972
+ let result = if age >= 18 then "adult" else "minor" end;
972
973
 
973
- // Nested ternary
974
+ // Nested conditional
974
975
  let score = 85;
975
- let category = score >= 90 ? "A" : score >= 80 ? "B" : "C";
976
+ let category = if score >= 90 then "A" else if score >= 80 then "B" else "C" end;
976
977
 
977
978
  // With complex expressions
978
979
  let isLoggedIn = () -> true;
979
980
  let hasPermission = () -> true;
980
- let status = isLoggedIn() && hasPermission() ? "authorized" : "unauthorized";
981
+ let status = if isLoggedIn() && hasPermission() then "authorized" else "unauthorized" end;
981
982
  ```
982
983
 
983
984
  ## Variable Names
984
985
 
985
- Dvala is generous with variable naming conventions, allowing a wide range of characters that would be invalid in many other programming languages.
986
+ Dvala uses JavaScript-style identifiers for variable names.
986
987
 
987
988
  ### Basic Rules
988
989
 
989
- Variable names in Dvala can contain almost any character except for a small set of reserved symbols. The only restrictions are:
990
-
991
- **Illegal characters anywhere in a variable name:**
992
- - Parentheses: `(` `)`
993
- - Brackets: `[` `]`
994
- - Braces: `{` `}`
995
- - Quotes: `'` `"` `` ` ``
996
- - Punctuation: `,` `.` `;`
997
- - Whitespace: spaces, newlines, tabs
998
-
999
- **Additional restrictions for the first character:**
1000
- - Cannot start with digits `0-9`
990
+ Variable names must match the pattern `[a-zA-Z_$][a-zA-Z0-9_$]*`:
1001
991
 
1002
- ### Unicode and Emoji Support
1003
-
1004
- Beyond these minimal restrictions, Dvala supports Unicode characters, including emojis, in variable names:
992
+ - **First character:** a letter (`a-z`, `A-Z`), underscore (`_`), or dollar sign (`$`)
993
+ - **Subsequent characters:** letters, digits (`0-9`), underscores, or dollar signs
1005
994
 
1006
995
  ```dvala
1007
- // Unicode characters are welcome
1008
- let résultat = 42;
1009
- let naïve = "simple approach";
1010
- let coöperation = "working together";
1011
-
1012
- // Emojis work too!
1013
- let 😅 = "grinning face with sweat";
1014
- let 🚀 = "rocket ship";
1015
- let result = 😅 ++ " " ++ 🚀;
1016
- // => "grinning face with sweat rocket ship"
996
+ let userName = "alice";
997
+ let isValid = true;
998
+ let _private = 42;
999
+ let $special = "dollar";
1000
+ let counter2 = 0;
1017
1001
  ```
1018
1002
 
1019
1003
  ### Quoted Variable Names
1020
1004
 
1021
- For cases where you need to use the normally illegal characters in variable names, Dvala supports quoted variable names using single quotes:
1005
+ For cases where you need characters outside the normal rules, Dvala supports quoted variable names using single quotes:
1022
1006
 
1023
1007
  ```dvala
1024
1008
  // Variables with spaces and special characters
1025
1009
  let 'A strange variable' = 42;
1026
1010
  let 'user.name' = "John Doe";
1027
1011
  let 'data[0]' = "first element";
1028
- let 'function()' = "callable";
1029
1012
 
1030
1013
  // Access them the same way
1031
1014
  'A strange variable' + 8;
1032
1015
  // => 50
1033
1016
  ```
1034
-
1035
- ### Practical Examples
1036
-
1037
- Here are some examples showcasing the flexibility of Dvala variable naming:
1038
-
1039
- ```dvala
1040
- // Mathematical notation with Greek letters (avoiding reserved symbols)
1041
- let α = 0.5;
1042
- let β = 1.2;
1043
- let γ = 2.0;
1044
- let Δ = β - α;
1045
-
1046
- // Descriptive names with special characters
1047
- let user-name = "alice";
1048
- let is-valid? = true;
1049
- let counter! = 0;
1050
-
1051
- // Mixed styles
1052
- let dataSet₁ = [1, 2, 3];
1053
- let dataSet₂ = [4, 5, 6];
1054
- let 🔧config = { debug: true };
1055
- ```
1056
-
1057
- ### Important: Operator Spacing
1058
-
1059
- Due to Dvala' flexible variable naming, **operators must be separated by whitespace**. This is crucial to understand:
1060
-
1061
- ```dvala
1062
- // This is a variable name, NOT addition!
1063
- let x+1 = 42;
1064
- let result1 = x+1; // => 42
1065
-
1066
- // To perform addition, use spaces
1067
- let x = 5;
1068
- let result2 = x + 1; // => 6
1069
-
1070
- // More examples of what looks like operations but are actually variable names
1071
- let a-b = "subtraction variable";
1072
- let c*d = "multiplication variable";
1073
- let e/f = "division variable";
1074
- let g<h = "comparison variable";
1075
-
1076
- // To use these as actual operations, add spaces
1077
- let a = 10;
1078
- let b = 3;
1079
- let a-sum = a + b; // Addition
1080
- let a-diff = a - b; // Subtraction
1081
- let a-prod = a * b; // Multiplication
1082
- let a-quot = a / b; // Division
1083
- let a-comp = a < b; // Comparison
1084
- ```
1085
-
1086
- Without whitespace, Dvala treats the entire sequence as a single variable identifier. This applies to all operators, including comparison operators, logical operators, and arithmetic operators.
1087
-
1088
- This flexibility allows for expressive and readable code while maintaining the functional programming paradigm that Dvala embodies.
1089
1017
  ## Operators and Functions
1090
1018
 
1091
1019
  ### Algebraic Notation
@@ -1248,10 +1176,10 @@ Dvala favors subject-first parameter order for better operator chaining:
1248
1176
 
1249
1177
  ```dvala
1250
1178
  // Function style
1251
- filter([1, 2, 3, 4], odd?); // => [1, 3]
1179
+ filter([1, 2, 3, 4], isOdd); // => [1, 3]
1252
1180
 
1253
1181
  // Operator style (more readable)
1254
- [1, 2, 3, 4] filter odd?; // => [1, 3]
1182
+ [1, 2, 3, 4] filter isOdd; // => [1, 3]
1255
1183
  ```
1256
1184
 
1257
1185
  ### Pipe Operator
@@ -1260,18 +1188,18 @@ The pipe operator `|>` passes the result of the left expression as the first arg
1260
1188
 
1261
1189
  ```dvala
1262
1190
  // Without pipe operator
1263
- reduce(map(filter([1, 2, 3, 4, 5, 6], odd?), -> $ * $), +, 0);
1191
+ reduce(map(filter([1, 2, 3, 4, 5, 6], isOdd), -> $ * $), +, 0);
1264
1192
 
1265
1193
  // With pipe operator (much more readable)
1266
1194
  [1, 2, 3, 4, 5, 6]
1267
- |> filter(_, odd?)
1195
+ |> filter(_, isOdd)
1268
1196
  |> map(_, -> $ * $)
1269
1197
  |> reduce(_, +, 0);
1270
1198
  // => 35
1271
1199
 
1272
1200
  // Simple transformations
1273
1201
  "hello world"
1274
- |> upper-case
1202
+ |> upperCase
1275
1203
  |> split(_, " ")
1276
1204
  |> reverse
1277
1205
  |> join(_, "-");
@@ -1287,7 +1215,7 @@ reduce(map(filter([1, 2, 3, 4, 5, 6], odd?), -> $ * $), +, 0);
1287
1215
  // Data processing pipeline
1288
1216
  { numbers: [1, 2, 3, 4, 5], multiplier: 3 }
1289
1217
  |> get(_, "numbers")
1290
- |> filter(_, even?)
1218
+ |> filter(_, isEven)
1291
1219
  |> map(_, *(_, 3))
1292
1220
  |> reduce(_, +, 0);
1293
1221
  // => 18 (even numbers [2, 4] -> [6, 12] -> sum = 18)
@@ -1311,8 +1239,7 @@ Here's the complete precedence table, from highest to lowest:
1311
1239
  | 5 | `&` `xor` `\|` | Bitwise operations | `4 \| 2 & 1` → `4 \| 0` → `4` |
1312
1240
  | 4 | `&&` `\|\|` `??` | Logical operations | `true && false \|\| true` → `false \|\| true` → `true` |
1313
1241
  | 3 | *function operators* | Binary functions used as operators | `5 max 3 + 2` → `5 max 5` → `5` |
1314
- | 2 | `\|>` | Pipe operator | `[1,2] \|> map(_, inc) \|> sum` |
1315
- | 1 | `?` `:` | Conditional (ternary) operator | `true ? 1 + 2 : 3` → `true ? 3 : 3` → `3` |
1242
+ | 2 | `\|>` | Pipe operator | `[1,2] \|> map(_, inc) \|> reduce(_, 0, +)` |
1316
1243
 
1317
1244
  #### Examples of Precedence in Action
1318
1245
 
@@ -1330,11 +1257,11 @@ Here's the complete precedence table, from highest to lowest:
1330
1257
  3 > 2 && 1 < 2; // => true && true = true
1331
1258
 
1332
1259
  // Pipe has very low precedence
1333
- let vec = import(vector);
1260
+ let { sum } = import(vector);
1334
1261
  [1, 2, 3] |> map(_, inc) |> sum; // Evaluates left to right
1335
1262
 
1336
- // Conditional has lowest precedence
1337
- true ? 2 + 3 : 4 + 5; // => true ? 5 : 9 = 5
1263
+ // Conditional expression
1264
+ if true then 2 + 3 else 4 + 5 end; // => 5
1338
1265
  ```
1339
1266
 
1340
1267
  #### Using Parentheses
@@ -1356,7 +1283,7 @@ let d = true;
1356
1283
  let e = false;
1357
1284
  let f = 10;
1358
1285
  let g = 5;
1359
- ((a + b) * c) > (d && e ? f : g) // => (5 * 4) > (false ? 10 : 5) = 20 > 5 = true;
1286
+ ((a + b) * c) > (if d && e then f else g end) // => (5 * 4) > (if false then 10 else 5 end) = 20 > 5 = true;
1360
1287
  ```
1361
1288
 
1362
1289
  #### Associativity
@@ -1427,7 +1354,7 @@ let square = x -> x * x;
1427
1354
  ### Factorial
1428
1355
 
1429
1356
  ```dvala
1430
- let factorial = n -> n <= 1 ? 1 : n * self(n - 1);
1357
+ let factorial = (n) -> if n <= 1 then 1 else n * self(n - 1) end;
1431
1358
 
1432
1359
  factorial(5); // => 120
1433
1360
  ```
@@ -1439,13 +1366,13 @@ let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
1439
1366
 
1440
1367
  // Get even numbers squared
1441
1368
  let evenSquares = numbers
1442
- |> filter(_, even?)
1369
+ |> filter(_, isEven)
1443
1370
  |> map(_, -> $ * $);
1444
1371
  // => [4, 16, 36, 64, 100]
1445
1372
 
1446
1373
  // Sum of odd numbers
1447
1374
  let oddSum = numbers
1448
- |> filter(_, odd?)
1375
+ |> filter(_, isOdd)
1449
1376
  |> reduce(_, +, 0);
1450
1377
  // => 25
1451
1378
  ```
@@ -1465,7 +1392,7 @@ let wordCount = text
1465
1392
  let longWords = text
1466
1393
  |> split(_, #"\s+")
1467
1394
  |> filter(_, -> count($) > 4)
1468
- |> map(_, upper-case);
1395
+ |> map(_, upperCase);
1469
1396
  // => ["HELLO,", "WORLD!", "TODAY?"]
1470
1397
  ```
1471
1398
 
@@ -1480,7 +1407,7 @@ let users = [
1480
1407
  ];
1481
1408
 
1482
1409
  // Group by department and get average age
1483
- let grouped = users |> su.group-by(_, "department");
1410
+ let grouped = users |> su.groupBy(_, "department");
1484
1411
  let departmentAges = grouped
1485
1412
  |> entries(_)
1486
1413
  |> map(_, ([dept, people]) -> do