# Combinator-Based Architecture ## What is Combinator-Based Architecture? Combinator-based architecture means the entire language is built from simple, composable functions called **combinators**. There are no classes, no inheritance, no methods - everything is function composition. ```plaintext /* Everything is built from combinators */ /* map, filter, reduce, compose, pipe, each, via */ /* No classes, no inheritance, no methods */ ``` ## Why is This Esoteric? Most programming languages are built around objects, classes, and methods. Our language is built entirely around **function composition** and **combinators** - a completely different paradigm. ## Core Combinators ### `map` - Transform Elements ```plaintext /* map applies a function to every element in a collection */ double : x -> x * 2; numbers : {1, 2, 3, 4, 5}; doubled : map @double numbers; /* {2, 4, 6, 8, 10} */ /* map works with any function */ increment : x -> x + 1; incremented : map @increment numbers; /* {2, 3, 4, 5, 6} */ ``` ### `filter` - Select Elements ```plaintext /* filter keeps elements that satisfy a condition */ is_even : x -> x % 2 = 0; numbers : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; evens : filter @is_even numbers; /* {2, 4, 6, 8, 10} */ /* filter with custom conditions */ is_greater_than_five : x -> x > 5; large_numbers : filter @is_greater_than_five numbers; /* {6, 7, 8, 9, 10} */ ``` ### `reduce` - Accumulate Elements ```plaintext /* reduce combines all elements into a single value */ numbers : {1, 2, 3, 4, 5}; sum : reduce @add 0 numbers; /* 15 */ product : reduce @multiply 1 numbers; /* 120 */ /* reduce with custom accumulation */ max_value : reduce @max 0 numbers; /* 5 */ min_value : reduce @min 1000 numbers; /* 1 */ ``` ### `each` - Multi-Argument Operations ```plaintext /* each applies a function to corresponding elements from multiple collections */ numbers1 : {1, 2, 3, 4, 5}; numbers2 : {10, 20, 30, 40, 50}; /* Element-wise addition */ sums : each @add numbers1 numbers2; /* {11, 22, 33, 44, 55} */ /* Element-wise multiplication */ products : each @multiply numbers1 numbers2; /* {10, 40, 90, 160, 250} */ ``` ## Function Composition Combinators ### `compose` - Mathematical Composition ```plaintext /* compose(f, g)(x) = f(g(x)) */ double : x -> x * 2; increment : x -> x + 1; square : x -> x * x; /* Compose functions */ double_then_increment : compose @increment @double; increment_then_square : compose @square @increment; /* Use composed functions */ result1 : double_then_increment 5; /* double(5)=10, increment(10)=11 */ result2 : increment_then_square 5; /* increment(5)=6, square(6)=36 */ ``` ### `pipe` - Pipeline Composition ```plaintext /* pipe(f, g)(x) = g(f(x)) - left to right */ double_then_square : pipe @double @square; result : double_then_square 5; /* double(5)=10, square(10)=100 */ ``` ### `via` - Natural Composition ```plaintext /* via provides natural composition syntax */ complex_transform : double via increment via square; result : complex_transform 3; /* square(3)=9, increment(9)=10, double(10)=20 */ ``` ## Building Complex Operations ### Data Processing Pipeline ```plaintext /* Build complex operations from simple combinators */ data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /* Pipeline: filter → map → reduce */ is_even : x -> x % 2 = 0; double : x -> x * 2; sum : x -> reduce @add 0 x; /* Combine combinators */ pipeline : sum via map @double via filter @is_even; result : pipeline data; /* 60 */ /* Step by step: 1. filter @is_even data → {2, 4, 6, 8, 10} 2. map @double {2, 4, 6, 8, 10} → {4, 8, 12, 16, 20} 3. sum {4, 8, 12, 16, 20} → 60 */ ``` ### Validation Chain ```plaintext /* Build validation from combinators */ 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; /* true (6 > 0, 6 % 2 = 0, 6 < 10) */ ``` ## Table-Specific Combinators The `t.` namespace provides table-specific combinators: ```plaintext /* Table operations as combinators */ data : {a: 1, b: 2, c: 3}; /* Get keys and values */ keys : t.keys data; /* {"a", "b", "c"} */ values : t.values data; /* {1, 2, 3} */ /* Check and get values */ has_a : t.has data "a"; /* true */ value_a : t.get data "a"; /* 1 */ /* Transform tables */ with_d : t.set data "d" 4; /* {a: 1, b: 2, c: 3, d: 4} */ without_b : t.delete data "b"; /* {a: 1, c: 3} */ /* Merge tables */ table1 : {a: 1, b: 2}; table2 : {c: 3, d: 4}; merged : t.merge table1 table2; /* {a: 1, b: 2, c: 3, d: 4} */ ``` ## Advanced Combinator Patterns ### Function Factories ```plaintext /* Create combinators that generate other combinators */ create_multiplier : factor -> multiply factor; double : create_multiplier 2; triple : create_multiplier 3; /* Use generated combinators */ numbers : {1, 2, 3, 4, 5}; doubled : map @double numbers; /* {2, 4, 6, 8, 10} */ tripled : map @triple numbers; /* {3, 6, 9, 12, 15} */ ``` ### Conditional Combinators ```plaintext /* Combinators that choose based on conditions */ conditional_map : condition transform_false transform_true -> when condition is true then transform_true _ then transform_false; /* Use conditional combinator */ is_positive : x -> x > 0; double : x -> x * 2; square : x -> x * x; conditional_transform : conditional_map is_positive @square @double; result : map conditional_transform {1, -2, 3, -4, 5}; /* Result: {1, -4, 9, -8, 25} (positive numbers squared, negative doubled) */ ``` ### Recursive Combinators ```plaintext /* Combinators that can be applied recursively */ repeat_transform : n transform -> when n is 0 then identity _ then compose transform (repeat_transform (n - 1) transform); /* Use recursive combinator */ double : x -> x * 2; double_three_times : repeat_transform 3 @double; result : double_three_times 5; /* 40 (5 * 2 * 2 * 2) */ ``` ## When to Use Combinators **Use combinators when:** - Processing collections of data - Building data transformation pipelines - Creating reusable function components - Working with functional programming patterns - Building complex operations from simple ones **Don't use combinators when:** - You need side effects (combinators are pure) - You need complex object-oriented patterns - You're working with simple, one-off operations - You need imperative control flow ## Common Patterns ```plaintext /* Pattern 1: Data transformation pipeline */ data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /* Build pipeline from combinators */ pipeline : sum via map @double via filter @is_even; result : pipeline data; /* 60 */ /* Pattern 2: Validation pipeline */ validate_user : user -> all_validations : validate_email via validate_age via validate_name; all_validations user; /* Pattern 3: Configuration builder */ build_config : base_config overrides -> t.merge base_config overrides; ``` ## Key Takeaways 1. **Function composition** - everything is built from function composition 2. **No objects** - no classes, inheritance, or methods 3. **Composable** - combinators can be combined into complex operations 4. **Pure functions** - no side effects, predictable behavior 5. **Mathematical thinking** - operations are mathematical transformations ## Why This Matters Combinator-based architecture makes the language fundamentally different: - **Mathematical foundation** - based on function theory and category theory - **Composability** - complex operations built from simple, reusable parts - **Predictability** - pure functions with no side effects - **Functional thinking** - encourages thinking in terms of transformations - **No state management** - no mutable state to manage This architecture makes the language feel more like mathematical notation than traditional programming! 🚀