about summary refs log tree commit diff stats
path: root/js/scripting-lang/design/HISTORY/FUNCTION_COMPOSITION_PLAN.md
diff options
context:
space:
mode:
Diffstat (limited to 'js/scripting-lang/design/HISTORY/FUNCTION_COMPOSITION_PLAN.md')
-rw-r--r--js/scripting-lang/design/HISTORY/FUNCTION_COMPOSITION_PLAN.md192
1 files changed, 192 insertions, 0 deletions
diff --git a/js/scripting-lang/design/HISTORY/FUNCTION_COMPOSITION_PLAN.md b/js/scripting-lang/design/HISTORY/FUNCTION_COMPOSITION_PLAN.md
new file mode 100644
index 0000000..34ee728
--- /dev/null
+++ b/js/scripting-lang/design/HISTORY/FUNCTION_COMPOSITION_PLAN.md
@@ -0,0 +1,192 @@
+# Function Composition & Currying Design Plan - REVISED
+
+## Current Issue Analysis
+
+### Problem Statement
+The current function application implementation has a fundamental flaw for function composition:
+
+```javascript
+f g x  // Currently parsed as: apply(apply(f, g), x)
+       // This fails because: apply(f, g) = NaN (f expects a number, not a function)
+       // Then: apply(NaN, x) = Error
+```
+
+### Root Cause
+1. **Left-associative parsing**: `f g x` → `(f g) x` → `apply(apply(f, g), x)`
+2. **Non-curried functions**: Functions expect specific argument types, not other functions
+3. **Missing composition semantics**: No built-in understanding of function composition
+
+## Design Decision: Simplified Approach
+
+### Option 1: Full Currying (Haskell-style) ❌
+**Why not**: Major architectural change, breaks existing code, complex implementation
+
+### Option 2: Explicit Composition Only ✅ **RECOMMENDED**
+**Why this is better**:
+- **No ambiguity**: `f via g x` is always composition, `f g x` is always left-associative application
+- **Backward compatible**: All existing code works unchanged
+- **Clear intent**: Explicit composition makes code more readable
+- **No complex detection**: No need for runtime type checking
+- **Natural language**: `via` reads like English and is self-documenting
+
+### Option 3: Hybrid Approach ❌
+**Why not**: Overcomplicated, introduces ambiguity, harder to understand
+
+## Recommended Solution: Explicit Composition Only
+
+### 1. Keep Current Function Application
+- `f x` → `apply(f, x)` (immediate application)
+- `f g x` → `apply(apply(f, g), x)` (left-associative, as currently implemented)
+- Functions remain non-curried by default
+- Maintains current behavior for simple cases
+
+### 2. Add Explicit Composition Keyword
+- `f via g` → `compose(f, g)` (explicit composition)
+- `f via g via h` → `compose(f, compose(g, h))` (right-associative)
+- `f via g x` → `apply(compose(f, g), x)` (composition then application)
+- Clear and explicit about intent
+
+### 3. Fix and Enhance @ Operator
+- `@f` → function reference (fix current parsing issues)
+- `map(@f, [1,2,3])` → pass function as argument
+- `when x is @f then ...` → pattern matching on functions
+- Essential for higher-order programming
+
+### 4. Enhanced Standard Library
+- Improve `compose` function to handle multiple arguments
+- Add `pipe` for left-to-right composition
+- Add `curry` and `uncurry` utilities for when needed
+
+## Implementation Plan
+
+### Phase 1: Lexer Enhancement
+- Add composition keyword (`via`)
+- Fix `@` operator parsing issues
+- Update token precedence
+
+### Phase 2: Parser Enhancement
+- Add `parseComposition()` function
+- Fix `parsePrimary()` to handle `@` operator correctly
+- Implement explicit composition parsing
+
+### Phase 3: Standard Library Enhancement
+- Improve `compose` function
+- Add `pipe` function
+- Add `curry`/`uncurry` utilities
+
+### Phase 4: Testing & Validation
+- Test all composition scenarios
+- Ensure backward compatibility
+- Performance testing
+
+## Syntax Examples
+
+### Current (Working)
+```javascript
+f : x -> x * 2;
+g : x -> x + 1;
+
+result1 : f x;        // apply(f, x) = 10
+result2 : f (g x);    // apply(f, apply(g, x)) = 12
+```
+
+### Proposed (Enhanced)
+```javascript
+f : x -> x * 2;
+g : x -> x + 1;
+
+result1 : f x;        // apply(f, x) = 10
+result2 : f via g x;  // apply(compose(f, g), x) = 12
+result3 : pipe(f, g) x; // apply(pipe(f, g), x) = 12
+result4 : @f;         // function reference to f
+result5 : map(@f, [1,2,3]); // [2, 4, 6]
+
+// Natural language examples
+data : [1, 2, 3, 4, 5];
+result6 : data via filter via map via reduce;  // Pipeline example
+result7 : x via abs via double via add(10);    // Mathematical pipeline
+```
+
+## Why `via` is Better Than `.`
+
+### 1. **Natural Language**
+- `f via g x` reads like "f via g applied to x"
+- `data via filter via map` reads like "data via filter via map"
+- More intuitive for non-FP developers
+
+### 2. **No Conflicts**
+- No confusion with decimal numbers
+- No conflict with object property access
+- Won't interfere with existing syntax
+
+### 3. **Clear Intent**
+- Explicitly indicates composition
+- Self-documenting code
+- No ambiguity about what's happening
+
+### 4. **Better Error Messages**
+- "Expected function after 'via'" is clearer than "Expected function after '.'"
+- More natural error reporting
+
+### 5. **Accessibility**
+- Lower learning curve
+- No prior FP knowledge needed
+- Intuitive for beginners
+
+## Backward Compatibility
+
+### Guaranteed to Work
+- All existing function calls: `f x`
+- All existing operator expressions: `x + y`
+- All existing function definitions
+- All existing when expressions
+- All existing table operations
+
+### New Features (Optional)
+- Explicit composition: `f via g`
+- Fixed function references: `@f`
+- Enhanced standard library functions
+
+## Why This Approach is Better
+
+### 1. Simplicity
+- No complex detection logic
+- No runtime type checking
+- Clear, predictable behavior
+
+### 2. Clarity
+- `f g x` always means `(f g) x`
+- `f via g x` always means `f(g(x))`
+- No ambiguity about intent
+
+### 3. Familiarity
+- `via` is intuitive and self-explanatory
+- No mathematical notation to learn
+- Easy to understand and teach
+
+### 4. Flexibility
+- Users can choose when to use composition
+- No forced architectural changes
+- Easy to extend later if needed
+
+## Next Steps
+
+1. **Implement Phase 1**: Add composition keyword to lexer, fix @ operator
+2. **Implement Phase 2**: Add composition parsing to parser
+3. **Implement Phase 3**: Enhance standard library
+4. **Test thoroughly**: Ensure all existing code still works
+5. **Document**: Update language documentation
+6. **Examples**: Create comprehensive examples
+
+## Success Criteria
+
+- [ ] `f via g x` works correctly for function composition
+- [ ] `@f` works correctly for function references
+- [ ] All existing code continues to work unchanged
+- [ ] Performance impact is minimal
+- [ ] Error messages are clear and helpful
+- [ ] Documentation is comprehensive
+
+## Conclusion
+
+The explicit composition approach using `via` is simpler, clearer, and more maintainable than the hybrid approach. It provides the functionality we need without the complexity and potential ambiguity of automatic detection. The `via` keyword makes the language more accessible and self-documenting, while maintaining all the power of functional composition. Combined with fixing the `@` operator, this gives us a powerful and clear functional programming language. 
\ No newline at end of file