feat: implement evidence passing for O(1) effect handler lookup
Interpreter changes: - Add evidence HashMap for O(1) handler lookup instead of O(n) stack search - Update eval_run to manage evidence when entering/exiting run blocks - Modify handle_effect to use evidence.get() instead of stack iteration C backend infrastructure: - Add handler structs (LuxConsoleHandler, LuxStateHandler, LuxReaderHandler) - Add LuxEvidence struct containing pointers to all handlers - Add default handlers that delegate to built-in implementations - Add Console.readLine built-in implementation Documentation: - Create docs/EVIDENCE_PASSING.md explaining design and implementation - Update docs/C_BACKEND.md with current progress Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -249,35 +249,43 @@ Koka also compiles to C with algebraic effects. Key differences:
|
||||
|
||||
---
|
||||
|
||||
## Current Progress
|
||||
|
||||
### Evidence Passing (Zero-Cost Effects) - PARTIALLY COMPLETE
|
||||
|
||||
**Interpreter:** ✅ Complete - O(1) HashMap lookup instead of O(n) stack search.
|
||||
|
||||
**C Backend Infrastructure:** ✅ Complete - Handler structs and evidence types generated.
|
||||
|
||||
**C Backend Threading:** 🔜 Planned - Passing evidence through function calls.
|
||||
|
||||
See [docs/EVIDENCE_PASSING.md](EVIDENCE_PASSING.md) for details.
|
||||
|
||||
---
|
||||
|
||||
## Future Roadmap
|
||||
|
||||
### Phase 1: Evidence Passing (Zero-Cost Effects)
|
||||
### Phase 1: Complete Evidence Passing in C Backend
|
||||
|
||||
**Goal:** Eliminate runtime effect handler lookup.
|
||||
**Goal:** Thread evidence through all effectful function calls.
|
||||
|
||||
**Current approach (slow):**
|
||||
```rust
|
||||
// O(n) search through handler stack
|
||||
for handler in self.handler_stack.iter().rev() {
|
||||
if handler.effect == request.effect {
|
||||
return handler.invoke(request);
|
||||
}
|
||||
}
|
||||
```
|
||||
**Current state:** Handler types (`LuxConsoleHandler`, etc.) and `LuxEvidence` struct
|
||||
are generated, but not yet used. Effect calls still use hardcoded `lux_console_print()`.
|
||||
|
||||
**Evidence passing (fast):**
|
||||
**Required changes:**
|
||||
```c
|
||||
typedef struct {
|
||||
Console* console;
|
||||
FileIO* fileio;
|
||||
} Evidence;
|
||||
// Current (hardcoded):
|
||||
void greet_lux(LuxString name) {
|
||||
lux_console_print(name);
|
||||
}
|
||||
|
||||
void greet(Evidence* ev, const char* name) {
|
||||
ev->console->print(ev, name); // Direct call, no search
|
||||
// Target (evidence passing):
|
||||
void greet_lux(LuxEvidence* ev, LuxString name) {
|
||||
ev->console->print(ev->console->env, name);
|
||||
}
|
||||
```
|
||||
|
||||
**Expected speedup:** 10-20x for effect-heavy code.
|
||||
**Expected speedup:** 10-20x for effect-heavy code (based on Koka benchmarks).
|
||||
|
||||
### Phase 2: Perceus Reference Counting
|
||||
|
||||
|
||||
Reference in New Issue
Block a user