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.
/* 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
/* 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.
/* 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.
/* 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!
/* 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
/* 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.
/* 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:
/* 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:
/* 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} */