I think the problem becomes knowing what to cache. In practice, you could end up caching many intermediate states that you don’t care about very much. It’s probably sufficient to cache the result of executing the function, and then invalidate the cache if it’s incorrect. In this example, it would probably mean something like saving the highlighted version and loading that one instead of your program. Indeed, we wouldn’t necessarily even need the semantic version, we could use one that just grabbed the colors and the text, and hydrated the semantic one in the background.
Git does this with nearly everything (and you can make it work for even more things if you want) most notably with the index. I don’t know if there is tooling to make it automatic, however, because you need to choose which data to cache (and how to cache it) carefully.
Neat! Thinking about it - you’d have to solve the ondisk fragmentation problem…. unless you said this would only work for ssds, then you could just do a straight log. It would be a big detriment to do this on top of yet another fs I think.
Defrag looks like flushing the cache. :)
This reminds me of what Lucid was building (which led to Xemacs). There was a database of c++ code, because parsing it repeatedly was very slow.
Or something about ccache and memory mapping parsed files into memory.
I think the runtime and the language and the OS would need to be merged. The JIT or runtime management system would need to weigh the cost of storing and retrieving the result vs re-running the computation. Computations across all invocations would need to be stored, so there would be some security issues. If you have infinite storage and the program runs infinitely long, it will memoize all possible states. Memoize all the things!