about summary refs log tree commit diff stats
path: root/js/scripting-lang/tutorials/02_Function_Composition.md
diff options
context:
space:
mode:
Diffstat (limited to 'js/scripting-lang/tutorials/02_Function_Composition.md')
-rw-r--r--js/scripting-lang/tutorials/02_Function_Composition.md138
1 files changed, 138 insertions, 0 deletions
diff --git a/js/scripting-lang/tutorials/02_Function_Composition.md b/js/scripting-lang/tutorials/02_Function_Composition.md
new file mode 100644
index 0000000..a6137b4
--- /dev/null
+++ b/js/scripting-lang/tutorials/02_Function_Composition.md
@@ -0,0 +1,138 @@
+# Function Composition
+
+## What is the `via` Operator?
+
+The `via` operator is a function composition operator that combines functions from right to left.
+
+```plaintext
+/* f via g = compose(f, g) */
+/* f via g via h = compose(f, compose(g, h)) */
+```
+
+The `via` operator is right-associative and matches mathematical notation where `(f ∘ g ∘ h)(x) = f(g(h(x)))`.
+
+```plaintext
+/* Define simple functions */
+double : x -> x * 2;
+increment : x -> x + 1;
+square : x -> x * x;
+
+/* Using via composition */
+result1 : double via increment 5;
+/* Result: 12 (5+1=6, 6*2=12) */
+
+/* Chained via composition */
+result2 : double via increment via square 3;
+/* Result: 20 (3^2=9, 9+1=10, 10*2=20) */
+```
+
+The key insight is that `via` groups from right to left.
+
+```plaintext
+/* This expression: */
+double via increment via square 3
+
+/* Groups as: */
+double via (increment via square) 3
+
+/* Which translates to: */
+compose(double, compose(increment, square))(3)
+
+/* With the execution order of: */
+/* 1. square(3) = 9 */
+/* 2. increment(9) = 10 */
+/* 3. double(10) = 20 */
+```
+
+## Precedence rules and `via`
+
+The `via` operator has higher precedence than function application:
+
+```plaintext
+/* via binds tighter than juxtaposition */
+double via increment 5
+
+/* This is parsed as: */
+(double via increment) 5
+```
+
+## More examples
+
+```plaintext
+/* Data processing pipeline */
+data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+is_even : x -> x % 2 = 0;
+double : x -> x * 2;
+sum : x -> reduce add 0 x;
+
+/* Pipeline using via */
+process_pipeline : sum via map double via filter is_even;
+result : process_pipeline data;
+/* Reads: sum via (map double via filter is_even) */
+/* Result: 60 */
+```
+
+You'll note that we don't need to use `@` here -- `via` is kinda special-cased because it is an ergonomic feature. It can work with function names directly because it's specifically for function composition. Higher-order functions like `map`, `filter`, and `reduce` require explicit function references using `@` because they need a way to distinguish between calling a function immediately vs passing it as an argument while `via` only ever takes in functions.
+
+
+A goal with the `via` operator is to align with mathematical function composition:
+
+```plaintext
+/* Mathematical: (f ∘ g ∘ h)(x) = f(g(h(x))) */
+/* Baba Yaga: f via g via h x = f(g(h(x))) */
+```
+
+## When to Use `via`
+
+**Use `via` when you want:**
+- Natural reading: `f via g via h` reads as "f then g then h"
+- Mathematical notation: Matches `(f ∘ g ∘ h)` notation
+- Concise syntax: Shorter than nested `compose` calls
+- Right-to-left flow: When you think of data flowing right to left
+
+**Don't use `via` when:**
+- You need left-to-right composition (use `pipe`)
+- You want explicit mathematical style (use `compose`)
+- You're working with simple function calls (use juxtaposition)
+- If you don't wanna
+
+## Common Patterns
+
+```plaintext
+/* Data transformation pipeline */
+data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
+is_even : x -> x % 2 = 0;
+double : x -> x * 2;
+sum : x -> reduce add 0 x;
+
+/* Pipeline: filter → map → reduce */
+process_pipeline : sum via map double via filter is_even;
+result : process_pipeline data;
+/* Result: 60 (filter evens: {2,4,6,8,10}, double: {4,8,12,16,20}, sum: 60) */
+
+/* Validation chain */
+validate_positive : x -> x > 0;
+validate_even : x -> x % 2 = 0;
+validate_small : x -> x < 10;
+
+/* Chain validations */
+all_validations : validate_small via validate_even via validate_positive;
+result : all_validations 6;  /* 6 > 0, 6 % 2 = 0, 6 < 10 */
+/* Result: true */
+```
+
+## Debugging `via` Chains
+
+To understand execution order, break down the chain:
+
+```plaintext
+/* Complex chain: */
+result : square via double via increment via square 2;
+
+/* Break it down: */
+/* 1. square(2) = 4 */
+/* 2. increment(4) = 5 */
+/* 3. double(5) = 10 */
+/* 4. square(10) = 100 */
+/* Result: 100 */
+```
\ No newline at end of file