07_Function_References

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

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