|
| 1 | +# Syntax Gotchas |
| 2 | + |
| 3 | +This document records unintuitive consequences of Eucalypt's syntax design decisions that can lead to subtle bugs or confusion. These are documented here until such time as we can implement a linter or improve error messages to catch them more clearly. |
| 4 | + |
| 5 | +## Operator Precedence Issues |
| 6 | + |
| 7 | +### Field Access vs Catenation |
| 8 | + |
| 9 | +**Problem**: The lookup operator (`.`) has higher precedence (90) than catenation (precedence 20), which can lead to unexpected parsing. |
| 10 | + |
| 11 | +**Gotcha**: Writing `objects head.id` is parsed as `objects (head.id)` rather than `(objects head).id`. |
| 12 | + |
| 13 | +**Example**: |
| 14 | +```eu |
| 15 | +# This doesn't work as expected: |
| 16 | +objects: range(0, 5) map({ id: _ }) |
| 17 | +result: objects head.id # Parsed as: objects (head.id) |
| 18 | +
|
| 19 | +# Correct syntax requires parentheses: |
| 20 | +result: (objects head).id # Explicitly groups the field access |
| 21 | +``` |
| 22 | + |
| 23 | +**Error Message**: When this occurs, you may see confusing errors like: |
| 24 | +- `cannot return function into case table without default` |
| 25 | +- `bad index 18446744073709551615 into environment` (under memory pressure) |
| 26 | + |
| 27 | +**Solution**: Always use parentheses to group the expression you want to access fields from: |
| 28 | +- Use `(expression).field` instead of `expression target.field` |
| 29 | +- Be explicit about precedence when combining catenation with field access |
| 30 | + |
| 31 | +**Reference**: Operator precedences are defined in `src/core/metadata.rs:165-186`: |
| 32 | +- `lookup` (`.`): precedence 90 |
| 33 | +- `cat` (catenation): precedence 20 |
| 34 | + |
| 35 | +## Anaphora and Function Syntax |
| 36 | + |
| 37 | +### Lambda Syntax Does Not Exist |
| 38 | + |
| 39 | +**Problem**: Eucalypt does not have lambda expressions like other functional languages. |
| 40 | + |
| 41 | +**Gotcha**: Attempting to write lambda-style syntax will cause syntax errors. |
| 42 | + |
| 43 | +**Invalid Examples**: |
| 44 | +```eu |
| 45 | +# These syntaxes DO NOT exist in Eucalypt: |
| 46 | +map(\x -> x + 1) # Invalid |
| 47 | +map(|x| x + 1) # Invalid |
| 48 | +map(fn(x) => x + 1) # Invalid |
| 49 | +map(λx.x + 1) # Invalid |
| 50 | +``` |
| 51 | + |
| 52 | +**Correct Approach**: Use anaphora (`_`, `_0`, `_1`, etc.) or define named functions: |
| 53 | +```eu |
| 54 | +# Using anaphora: |
| 55 | +map(_ + 1) |
| 56 | +
|
| 57 | +# Using named function: |
| 58 | +add-one(x): x + 1 |
| 59 | +map(add-one) |
| 60 | +
|
| 61 | +# Using block with anaphora for complex expressions: |
| 62 | +map({ result: _ + 1, doubled: _ * 2 }) |
| 63 | +``` |
| 64 | + |
| 65 | +**Reference**: See `docs/anaphora-and-lambdas.md` for detailed explanation of anaphora usage. |
| 66 | + |
| 67 | +## Future Improvements |
| 68 | + |
| 69 | +These gotchas highlight areas where the language could benefit from: |
| 70 | + |
| 71 | +1. **Better Error Messages**: More specific error messages when precedence issues occur |
| 72 | +2. **Linting Rules**: Static analysis to catch common precedence mistakes |
| 73 | +3. **IDE Support**: Syntax highlighting and warnings for ambiguous expressions |
| 74 | +4. **Documentation**: Better examples showing correct precedence usage |
| 75 | + |
| 76 | +## Contributing |
| 77 | + |
| 78 | +When you encounter a new syntax gotcha, please add it to this document with: |
| 79 | +- A clear description of the problem |
| 80 | +- Example of incorrect usage |
| 81 | +- Example of correct usage |
| 82 | +- The error message(s) that result |
| 83 | +- Reference to relevant code or documentation |
0 commit comments