docs: update documentation with RC implementation status

- C_BACKEND.md: Update memory management from "Leaks" to "Scope-based RC",
  update comparison tables with Koka/Rust/Zig/Go
- LANGUAGE_COMPARISON.md: Add status column to gap tables, add RC row
- OVERVIEW.md: Add C backend RC to completed features, update limitations
- REFERENCE_COUNTING.md: Add "Path to Koka/Rust Parity" section with:
  - What we have vs what Koka/Rust have
  - Remaining work for full memory safety (~230 lines)
  - Performance optimizations for Koka parity (~600 lines)
  - Cycle detection strategy

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-02-14 13:05:17 -05:00
parent b1cffadc83
commit b2f4beeaa2
4 changed files with 154 additions and 36 deletions

View File

@@ -363,7 +363,114 @@ void lux_check_leaks() {
---
## Path to Koka/Rust Parity
### What We Have Now (Basic RC)
Our current implementation provides:
- **Deterministic cleanup** - Memory freed at predictable points (scope exit)
- **No GC pauses** - Unlike Go/Java, latency is predictable
- **Leak detection** - Debug mode catches memory leaks during development
- **No manual management** - Unlike C/Zig, programmer doesn't call free()
### What Koka Has (Perceus RC)
Koka's Perceus system adds several optimizations we don't have:
| Feature | Description | Benefit | Complexity |
|---------|-------------|---------|------------|
| **Last-use analysis** | Detect when a variable's final use allows ownership transfer | Avoid unnecessary copies | Medium |
| **Reuse (FBIP)** | When rc=1, mutate in-place instead of copy | Major performance boost | High |
| **Drop specialization** | Generate type-specific drop instead of polymorphic | Fewer branches, faster | Low |
| **Drop fusion** | Combine multiple consecutive drops | Fewer function calls | Medium |
| **Borrow inference** | Avoid incref when borrowing temporaries | Reduce RC overhead | High |
### What Rust Has (Ownership)
Rust's ownership system is fundamentally different:
| Aspect | Rust | Lux RC | Tradeoff |
|--------|------|--------|----------|
| **When checked** | Compile-time | Runtime | Rust catches bugs earlier |
| **Runtime cost** | Zero | RC operations | Rust is faster |
| **Learning curve** | Steep (borrow checker) | Gentle | Lux is easier to learn |
| **Expressiveness** | Limited by lifetimes | Unrestricted | Lux is more flexible |
| **Cycles** | Prevented by design | Would leak | Rust handles more patterns |
**Key insight:** We can never match Rust's zero-overhead guarantees because ownership is checked at compile time. RC always has runtime cost. But we can be as good as Koka.
### Remaining Work for Full Memory Safety
#### Phase A: Complete Coverage (Prevent All Leaks)
1. **Closure RC** - Environments should be RC-managed
- Allocate env with `lux_rc_alloc`
- Drop env when closure is dropped
- ~50 lines in `emit_lambda`
2. **ADT RC** - Algebraic data types with heap fields
- Track which variants contain RC fields
- Generate drop functions for each ADT
- ~100 lines
3. **Early return handling** - Cleanup all scopes on return
- Current impl handles simple cases
- Need nested scope cleanup
- ~30 lines
4. **Complex conditionals** - If/else creating RC values
- Switch from ternary to if-statements
- Track RC creation in branches
- ~50 lines
#### Phase B: Performance Optimizations (Match Koka)
1. **Last-use optimization**
- Track variable liveness
- Skip incref on last use (transfer ownership)
- Requires dataflow analysis
- ~200 lines
2. **Reuse analysis (FBIP)**
- Detect `rc=1` at update sites
- Mutate in-place instead of copy
- Major change to list operations
- ~300 lines
3. **Drop specialization**
- Generate per-type drop functions
- Eliminate polymorphic dispatch
- ~100 lines
### Estimated Effort
| Phase | Description | Lines | Priority |
|-------|-------------|-------|----------|
| A1 | Closure RC | ~50 | P0 - Closures leak |
| A2 | ADT RC | ~100 | P1 - ADTs leak |
| A3 | Early returns | ~30 | P1 - Edge cases |
| A4 | Conditionals | ~50 | P2 - Uncommon |
| B1 | Last-use opt | ~200 | P3 - Performance |
| B2 | Reuse (FBIP) | ~300 | P3 - Performance |
| B3 | Drop special | ~100 | P3 - Performance |
**Phase A total: ~230 lines** - Gets us to "no leaks"
**Phase B total: ~600 lines** - Gets us to Koka-level performance
### Cycle Detection
RC cannot handle cycles (A → B → A). Options:
1. **Ignore** - Cycles are rare in functional code (our current approach)
2. **Weak references** - Programmer marks back-edges
3. **Cycle collector** - Periodic scan for cycles (adds GC-like pauses)
Koka also ignores cycles, relying on functional programming's natural acyclicity.
---
## References
- [Perceus Paper](https://www.microsoft.com/en-us/research/publication/perceus-garbage-free-reference-counting-with-reuse/)
- [Koka Reference Counting](https://koka-lang.github.io/koka/doc/book.html)
- [Rust Ownership](https://doc.rust-lang.org/book/ch04-00-understanding-ownership.html)