about summary refs log tree commit diff stats
path: root/js/scripting-lang/tutorials/04_Currying.md
diff options
context:
space:
mode:
Diffstat (limited to 'js/scripting-lang/tutorials/04_Currying.md')
-rw-r--r--js/scripting-lang/tutorials/04_Currying.md167
1 files changed, 167 insertions, 0 deletions
diff --git a/js/scripting-lang/tutorials/04_Currying.md b/js/scripting-lang/tutorials/04_Currying.md
new file mode 100644
index 0000000..55bd3bf
--- /dev/null
+++ b/js/scripting-lang/tutorials/04_Currying.md
@@ -0,0 +1,167 @@
+# 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} */
+```
\ No newline at end of file