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.
/* @ 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
/* 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:
/* 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
/* 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
/* 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
/* 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
/* 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:
/* 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:
/* 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:
/* 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
/* 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
- @ symbol - creates function references
- No immediate execution - function is not called when referenced
- Combinator compatibility - works with
map
,filter
,reduce
,each
- Composition support - works with
compose
,pipe
,via
- 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! 🚀