Sprout v0.1.4 makes the tree-walker faster by cutting two allocations it was making for nothing — found by the benchmark suite. Both are pure internal speedups: identical semantics, no language change, the freeze holds.
Pay only for the scopes you use
- Repeat loops skip the per-turn scope when the body makes nothing.
repeatallocated a fresh environment every iteration to scope the body'smakes — even when there are none. Now a make-free body runs straight in the parent scope. Closures, nestedmakes, andstop/skipbehave exactly as before (an empty scope is invisible).loop: ~800 → ~165 ms (~5×);list_build: ~160 → ~90 ms. - Environments borrow variable names instead of copying them. Every definition
strdup'd its name — including a recursive call binding its parameters on every call. Those names are permanent AST text, so there's nothing to copy. Lighter GC pressure everywhere;fib: ~1960 → ~1790 ms.
Verified
The full suite + examples pass normally and under SPROUT_GC_STRESS=1 (collect on every statement), plus a new tests/loop_scope.sprout covering the edge cases the elision touches. AddressSanitizer + GC-stress green in CI on Linux.
This keeps Sprout a simple tree-walking interpreter — no second execution engine to maintain. A bytecode VM remains a deliberate, separate call, since that simplicity is a design goal.
Windows installer: SproutSetup.exe below.