diff options
Diffstat (limited to 'js/scripting-lang/tutorials/07_Function_References.md')
-rw-r--r-- | js/scripting-lang/tutorials/07_Function_References.md | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/js/scripting-lang/tutorials/07_Function_References.md b/js/scripting-lang/tutorials/07_Function_References.md new file mode 100644 index 0000000..4ca1616 --- /dev/null +++ b/js/scripting-lang/tutorials/07_Function_References.md @@ -0,0 +1,220 @@ +# Function References with `@` Symbol + +## What are Function References? + +Function references allow you to pass functions as values without calling them immediately. The `@` symbol creates a reference to a function. + +```plaintext +/* @ symbol for function references */ +double : x -> x * 2; +numbers : {1, 2, 3}; +result : map @double numbers; /* @double is a function reference */ +``` + +## Why is This Esoteric? + +The `@` symbol for function references is unique to our language. Most languages use just the function name or different syntax like `&function` or `function.bind()`. + +## Basic Examples + +```plaintext +/* Define a function */ +double : x -> x * 2; + +/* Function reference vs function call */ +function_ref : @double; /* Reference to the function */ +function_call : double 5; /* Call the function with argument 5 */ + +/* Use function reference with combinators */ +numbers : {1, 2, 3, 4, 5}; +doubled : map @double numbers; /* {2, 4, 6, 8, 10} */ +``` + +## How It Works + +The `@` symbol tells the language to treat the identifier as a function reference rather than calling the function: + +```plaintext +/* Without @ - function is called immediately */ +result1 : map double numbers; /* Error: double is not a function reference */ + +/* With @ - function reference is passed */ +result2 : map @double numbers; /* Works: @double is a function reference */ +``` + +## Common Use Cases + +### With `map` +```plaintext +/* Map function references over collections */ +numbers : {1, 2, 3, 4, 5}; + +/* Arithmetic functions */ +doubled : map @double numbers; /* {2, 4, 6, 8, 10} */ +incremented : map @increment numbers; /* {2, 3, 4, 5, 6} */ +squared : map @square numbers; /* {1, 4, 9, 16, 25} */ + +/* Custom functions */ +add_ten : x -> x + 10; +plus_ten : map @add_ten numbers; /* {11, 12, 13, 14, 15} */ +``` + +### With `filter` +```plaintext +/* Filter with function references */ +numbers : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + +/* Built-in comparison functions */ +evens : filter @is_even numbers; /* {2, 4, 6, 8, 10} */ +positives : filter @is_positive numbers; /* {1, 2, 3, 4, 5, 6, 7, 8, 9, 10} */ + +/* Custom filter functions */ +is_greater_than_five : x -> x > 5; +large_numbers : filter @is_greater_than_five numbers; /* {6, 7, 8, 9, 10} */ +``` + +### With `reduce` +```plaintext +/* Reduce with function references */ +numbers : {1, 2, 3, 4, 5}; + +/* Arithmetic operations */ +sum : reduce @add 0 numbers; /* 15 */ +product : reduce @multiply 1 numbers; /* 120 */ + +/* Custom reduce functions */ +max_value : reduce @max 0 numbers; /* 5 */ +min_value : reduce @min 1000 numbers; /* 1 */ +``` + +### With `each` +```plaintext +/* Each with function references */ +numbers1 : {1, 2, 3, 4, 5}; +numbers2 : {10, 20, 30, 40, 50}; + +/* Element-wise operations */ +sums : each @add numbers1 numbers2; /* {11, 22, 33, 44, 55} */ +products : each @multiply numbers1 numbers2; /* {10, 40, 90, 160, 250} */ +``` + +## Function Composition with References + +Function references work seamlessly with composition: + +```plaintext +/* Compose function references */ +double : x -> x * 2; +increment : x -> x + 1; +square : x -> x * x; + +/* Compose references */ +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 */ +``` + +## The `via` Operator with References + +Function references work with the `via` operator: + +```plaintext +/* Via with function references */ +result1 : @double via @increment 5; /* 12 */ +result2 : @double via @increment via @square 3; /* 20 */ + +/* Complex pipeline */ +pipeline : @sum via @map @double via @filter @is_even; +result3 : pipeline {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /* 60 */ +``` + +## Table Operations with References + +The `t.` namespace functions can be referenced: + +```plaintext +/* Table operation references */ +data : {a: 1, b: 2, c: 3}; + +/* Get all keys */ +keys : @t.keys data; /* {"a", "b", "c"} */ + +/* Get all values */ +values : @t.values data; /* {1, 2, 3} */ + +/* Check if key exists */ +has_a : @t.has data "a"; /* true */ +``` + +## When to Use Function References + +**Use function references when:** +- Passing functions to combinators like `map`, `filter`, `reduce` +- Building function composition chains +- Creating reusable function components +- Working with higher-order functions +- Avoiding immediate function execution + +**Don't use function references when:** +- You want to call the function immediately +- You're working with simple function calls +- You need to pass arguments to the function + +## Common Patterns + +```plaintext +/* Pattern 1: Function pipelines */ +numbers : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + +/* Pipeline with references */ +pipeline : @sum via @map @double via @filter @is_even; +result : pipeline numbers; /* 60 */ + +/* Pattern 2: Reusable function components */ +double : x -> x * 2; +increment : x -> x + 1; +square : x -> x * x; + +/* Create reusable transformations */ +double_transform : @map @double; +increment_transform : @map @increment; +square_transform : @map @square; + +/* Use transformations */ +data : {1, 2, 3, 4, 5}; +doubled : double_transform data; /* {2, 4, 6, 8, 10} */ +incremented : increment_transform data; /* {2, 3, 4, 5, 6} */ +squared : square_transform data; /* {1, 4, 9, 16, 25} */ + +/* Pattern 3: Conditional function application */ +condition : true; +function_to_use : when condition is + true then @double + _ then @square; + +result : map function_to_use {1, 2, 3, 4, 5}; +/* Result depends on condition */ +``` + +## Key Takeaways + +1. **@ symbol** - creates function references +2. **No immediate execution** - function is not called when referenced +3. **Combinator compatibility** - works with `map`, `filter`, `reduce`, `each` +4. **Composition support** - works with `compose`, `pipe`, `via` +5. **Higher-order functions** - enables passing functions as arguments + +## Why This Matters + +Function references with the `@` symbol make the language more functional: + +- **Higher-order functions** - functions can be passed as values +- **Composability** - functions can be combined and reused +- **Functional style** - emphasizes function composition over method calls +- **Clear syntax** - distinguishes between function calls and references +- **Reusability** - function references can be stored and reused + +This feature makes the language feel more like functional programming languages where functions are first-class citizens! 🚀 \ No newline at end of file |