Hi @harryprayiv
Regarding your question about the Value vs TAST paradox and the 240ms benchmark: your intuition was absolutely right.
In that specific micro-benchmark, the Go compiler was able to heavily optimize the tight loop (likely through aggressive inlining and branch prediction), which artificially brought the Value (tagged union) approach up to par with static Go.
However, as soon as we step out of these simple algorithms and run real-world, complex code (with deep ADTs, nested Records, and higher-order functions), the cumulative overhead of runtime tag checks and the limitations it imposes on the Go compiler become a real bottleneck too, even it’s still far better than using any everywhere. This is the first “ceiling” I hit. Value is a fantastic way to avoid boxing and GC pressure, but it cannot truly match native performance at scale.
This is exactly why TAST (and partial monomorphization) were the real game changers here. They aren’t meant to optimize simple loops (where Value already shines), but to break that ceiling on complex code.
To avoid any confusion for future readers, I have edited my original post regarding the 240/250ms benchmark.
I’ve also updated the benchmark links across my previous posts to ensure they accurately reflect the historical state of those experiments (for instance, pointing to the exact snapshots where gopurs was hitting >100ms rather than the current ~67ms). Before TASTs, the best I could get was 1000ms. Yes… more than 1 second… At that point, I’d had 2 or 3 very very short nights in a row, and I had even almost given up on the project and on the hope of creating an effective compilation…
Once the project is mature, all the information will be included in the README.md file.
Thanks again for your sharp and constructive feedback. ![]()
(and as for the TAST improvements, I’m just getting started on them)






