# 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! 🚀