# Currying ## What is Partial Application? Partial application means that functions automatically return new functions when called with fewer arguments than they expect. This is also called currying. ```plaintext /* Functions automatically return new functions when partially applied */ add : x y -> x + y; add_five : add 5; /* Returns a function that adds 5 */ result : add_five 3; /* 8 */ ``` Most programming languages require explicit syntax for partial application or currying. When using Baba Yagay, every function is automatically curried. ## Basic Examples ```plaintext /* Define a two-argument function */ add : x y -> x + y; /* Call with both arguments */ result1 : add 5 3; /* 8 */ /* Call with one argument - returns a new function */ add_five : add 5; /* Returns: y -> 5 + y */ /* Call the returned function */ result2 : add_five 3; /* 8 */ /* Chain partial applications */ add_ten : add 10; /* y -> 10 + y */ add_ten_five : add_ten 5; /* 15 */ ``` ## How It Works Partial application happens automatically with nested function returns. ```plaintext /* When you define: add : x y -> x + y; */ /* Baba Yaga creates: add = x -> (y -> x + y) */ /* When you call: add 5 */ /* It returns: y -> 5 + y */ /* When you call: add 5 3 */ /* It calls: (y -> 5 + y)(3) = 5 + 3 = 8 */ ``` Partial application works with any number of arguments. ```plaintext /* Three-argument function */ multiply_add : x y z -> x * y + z; /* Partial application examples */ multiply_by_two : multiply_add 2; /* y z -> 2 * y + z */ multiply_by_two_add_ten : multiply_add 2 5; /* z -> 2 * 5 + z */ /* Full application */ result1 : multiply_add 2 5 3; /* 2 * 5 + 3 = 13 */ result2 : multiply_by_two 5 3; /* 2 * 5 + 3 = 13 */ result3 : multiply_by_two_add_ten 3; /* 2 * 5 + 3 = 13 */ ``` All standard library functions support partial application, too! ```plaintext /* Arithmetic functions */ double : multiply 2; /* x -> 2 * x */ increment : add 1; /* x -> x + 1 */ decrement : subtract 1; /* x -> x - 1 */ /* Comparison functions */ is_positive : greaterThan 0; /* x -> x > 0 */ is_even : equals 0; /* This won't work as expected - see below */ /* Logical functions */ always_true : logicalOr true; /* x -> true || x */ always_false : logicalAnd false; /* x -> false && x */ ``` ## Common Patterns ```plaintext /* Pattern 1: Creating specialized functions */ numbers : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /* Create specialized filters */ is_even : x -> x % 2 = 0; is_odd : x -> x % 2 = 1; is_greater_than_five : x -> x > 5; /* Use with map and filter - note the @ operator for higher-order functions */ evens : filter @is_even numbers; /* {2, 4, 6, 8, 10} */ odds : filter @is_odd numbers; /* {1, 3, 5, 7, 9} */ large_numbers : filter @is_greater_than_five numbers; /* {6, 7, 8, 9, 10} */ /* Pattern 2: Creating transformation functions */ double : multiply 2; triple : multiply 3; add_ten : add 10; /* Apply transformations - @ operator required for map */ doubled : map @double numbers; /* {2, 4, 6, 8, 10, 12, 14, 16, 18, 20} */ tripled : map @triple numbers; /* {3, 6, 9, 12, 15, 18, 21, 24, 27, 30} */ plus_ten : map @add_ten numbers; /* {11, 12, 13, 14, 15, 16, 17, 18, 19, 20} */ ``` You can use partial application with function composition. ```plaintext /* Create specialized functions */ double : multiply 2; increment : add 1; square : x -> x * x; /* Compose partially applied functions - @ operator required for compose */ double_then_increment : compose @increment @double; increment_then_square : compose @square @increment; /* Use in pipelines */ result1 : double_then_increment 5; /* double(5)=10, increment(10)=11 */ result2 : increment_then_square 5; /* increment(5)=6, square(6)=36 */ ``` ## Table Operations with Partial Application The `t.` namespace functions also support partial application: ```plaintext /* Create specialized table operations */ get_name : t.get "name"; get_age : t.get "age"; has_admin : t.has "admin"; /* Use with map - @ operator required for higher-order functions */ people : { alice: {name: "Alice", age: 30, admin: true}, bob: {name: "Bob", age: 25, admin: false}, charlie: {name: "Charlie", age: 35, admin: true} }; names : map @get_name people; /* {alice: "Alice", bob: "Bob", charlie: "Charlie"} */ ages : map @get_age people; /* {alice: 30, bob: 25, charlie: 35} */ admins : map @has_admin people; /* {alice: true, bob: false, charlie: true} */ ``` ## The `each` Combinator with Partial Application The `each` combinator works well with partial application: ```plaintext /* Create specialized comparison functions */ is_greater_than_three : x -> x > 3; is_less_than_seven : x -> x < 7; /* Use with each for element-wise comparison - @ operator required for each */ numbers : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; greater_than_three : each @is_greater_than_three numbers; /* Result: {false, false, false, true, true, true, true, true, true, true} */ less_than_seven : each @is_less_than_seven numbers; /* Result: {true, true, true, true, true, true, false, false, false, false} */ ```