A student tasked with converting arithmetic expressions into binary trees initially sought to build an evaluator for the exercise.
A student tasked with converting arithmetic expressions into binary trees initially sought to build an evaluator for the exercise. The project expanded to include closures, garbage collection, a custom memory allocator, a read-eval-print loop, and foreign function interface support, all implemented in C. The core challenge involved representing expressions as a graph structure where operations like addition were treated uniformly as functions, enabling a more flexible evaluation model.
The evaluator's design evolved to separate function representation from native code. Instead of relying on C function pointers, the system used closure nodes that stored parameter bindings and operation trees, allowing user-defined functions to be manipulated as first-class values. This required extending the environment table to map identifiers to node references, supporting both variables and functions within the same lookup mechanism.
Memory allocation presented significant hurdles. An initial arena allocator, limited to 1,024 nodes, caused crashes during recursive evaluations like Fibonacci(5). A chunk-based allocator resolved this by chaining memory blocks without relocating existing nodes. However, recursive evaluations still consumed excessive memory, with Fibonacci(40) requiring over 12 gigabytes before exhausting resources.
To address persistent memory usage, a mark-and-sweep garbage collector was implemented. This system tracked reachable nodes from root references, cleared unreferenced allocations, and reused freed memory. After integration, Fibonacci(40) executed within 1.7 megabytes of RAM, though evaluation remained slow due to the algorithm's exponential complexity and stop-the-world garbage collection pauses.
The project demonstrated how a simple academic exercise could lead to a functional language prototype with full closure support, custom memory management, and garbage collection. The final implementation could evaluate expressions like fib(5) correctly, though performance optimizations like tail-call elimination and generational garbage collection were planned for future iterations.
- Publisher
- Hacker News
- Reliability
- high
- Published
- 9/30/2026, 6:21:21 PM
- Retrieved
- 9/30/2026, 6:21:21 PM
- Relevance
- 80%
- Confidence
- 85%

