about summary refs log tree commit diff stats
path: root/util.h
blob: 76fc09f59b1089da9f3a851d1c9f2dbf0394f58f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Function Calls

## What is Juxtaposition?

In Baba Yaga you call functions by putting them next to each other.

```plaintext
/* 
   JavaScript: f(x, y)
    Baba Yaga: f x y
*/
```

## Basic Examples

```plaintext
/* Simple function calls */
add 5 3;           /* Instead of add(5, 3) */
multiply 4 7;      /* Instead of multiply(4, 7) */
subtract 10 3;     /* Instead of subtract(10, 3) */

/* Function calls with tables */
ally translates juxtaposition into nested calls to `apply`, so that ```plaintext /* f x y becomes: apply(apply(f, x), y) */ /* map double {1, 2, 3} becomes: apply(apply(map, double), {1, 2, 3}) */ ``` ## Precedence Rules Juxtaposition has lower precedence than operators, ```plaintext result : add 5 multiply 3 4; /* Parsed as: add 5 (multiply 3 4) */ /* Result: 5 + (3 * 4) = 17 */ /* Not as: (add 5 multiply) 3 4 */ ``` With Baba Yaga you'll use juxtaposition when you - call functions with arguments - build function composition chains - work with combinators like `map`, `filter`, `reduce` You won't use it, exactly, when you are - defining functions (use `:` and `->`) - assigning values (use `:`) - using operators (use `+`, `-`, `*`, etc.) ## Common Patterns ```plaintext /* Data processing pipeline */ data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; is_even : x -> x % 2 = 0; double : x -> x * 2; sum : x -> reduce add 0 x; /* Pipeline using juxtaposition */ result : sum map double filter is_even data; /* Reads: sum (map double (filter is_even data)) */ /* Result: 60 */ ``` ## Using Parentheses for Control Juxtaposition eliminates the need for parentheses in most cases, parentheses are available for when you need explicit control over precedence or grouping. ```plaintext /* Without parentheses - left-associative */ result1 : add 5 multiply 3 4; /* Parsed as: add 5 (multiply 3 4) */ /* Result: 5 + (3 * 4) = 17 */ /* With parentheses - explicit grouping */ result2 : add (add 1 2) (multiply 3 4); /* Explicitly: (1 + 2) + (3 * 4) = 3 + 12 = 15 */ /* Complex nested operations */ result3 : map double (filter is_even (map increment {1, 2, 3, 4, 5})); /* Step by step: 1. map increment {1, 2, 3, 4, 5} → {2, 3, 4, 5, 6} 2. filter is_even {2, 3, 4, 5, 6} → {2, 4, 6} 3. map double {2, 4, 6} → {4, 8, 12} */ /* Hard to read without parentheses */ complex : map double filter is_even map increment {1, 2, 3, 4, 5}; /* Much clearer with parentheses */ complex : map double (filter is_even (map increment {1, 2, 3, 4, 5})); /* Or break it into steps for maximum clarity */ step1 : map increment {1, 2, 3, 4, 5}; step2 : filter is_even step1; step3 : map double step2; ``` Parentheses are also helpful for debugging because they let you isolate specific pieces of a program or chain. ```plaintext data : {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; /* Test each step separately */ filtered : filter @is_even data; doubled : map @double filtered; final : reduce @add 0 doubled; /* Or use parentheses to test intermediate results */ test1 : filter is_even data; /* {2, 4, 6, 8, 10} */ test2 : map double (filter is_even data); /* {4, 8, 12, 16, 20} */ ``` ## Spacing Rules Baba Yaga uses spacing to distinguish between unary and binary operators...mostly just minus. - **Unary minus**: `-5` (no leading space) → `negate(5)` - **Binary minus**: `5 - 3` (spaces required) → `subtract(5, 3)` - **Legacy fallback**: `5-3``subtract(5, 3)` (but spaces are recommended) The parser distinguishes between these scenarios based off of spaces, and kinda best guess heuristics. It *should* work as expected in most cases. - **Unary minus** (negative numbers): `-5``negate(5)` - **Binary minus** (subtraction): `5 - 3``subtract(5, 3)` Spacing makes expressions less ambiguous. ### Common Patterns ```plaintext /* Function calls with negative numbers */ double : x -> x * 2; result : double -5; /* unary minus */ result2 : double (-5); /* explicit grouping */ /* Comparisons with negative numbers */ is_negative : x -> x < 0; test1 : is_negative -5; /* unary minus */ /* Complex expressions with negative numbers */ validate_age : age -> (age >= 0) and (age <= 120); test2 : validate_age -5; /* unary minus */ /* Arithmetic with proper spacing */ result3 : -5 + 3; /* unary minus + binary plus */ result4 : 5 - 3; /* binary minus with spaces */ result5 : (-5) + 3; /* explicit grouping */ ``` #### Best Practices - **Use spaces around binary operators**: `5 - 3`, `5 + 3`, `5 * 3` - **Unary minus works without parentheses**: `-5`, `f -5` - **Legacy syntax still works**: `(-5)`, `5-3` (but spaces are recommended) - **When in doubt, use spaces**: It makes code more readable and follows conventions #### When You Might Encounter This - **Arithmetic operations**: `-5 + 3`, `5 - 3`, `(-5) + 3` - **Comparisons**: `-5 >= 0`, `5 - 3 >= 0` - **Function calls**: `f -5`, `f (-5)`, `map double -3` - **Logical expressions**: `(-5 >= 0) and (-5 <= 120)` - **Pattern matching**: `when x is -5 then "negative five"` To make everyone's life easier, use spaces around binary operators.