However, you'll need quite a lot of tooling around this simple idea: where to store the class files and the hashes, should you commit it into source control, how to distribute the cache, can this be made multi-platform so it works on all developers' machines?
All solvable, but Unison already does all that, and more, with its single tool, the `ucm`.
As far as I understand, Unison's syntax has been designed specifically to avoid such cycles, although it supports recursive functions and inductive data types which refer to themselves such as lists. I'm not sure if, and if so, how, it would support mutually recursive functions or data types though. I suspect they're not supported for the reason that content-hashing becomes non-trivial.
If you wanted to generalize the solution to arbitrary languages, you would need to somehow sever the cycles, or come up with another solution to content-hashing which does not have the problem of Merkle-DAGs. Either way, you are looking at something non-trivial compared to having a language which simply forbids the cycles.
https://www.unisonweb.org/docs/faq/#how-does-hashing-work-fo...
The model also precludes cross-unit optimizations so there's a performance upper bound on compilation model that leaves it in the middle tier of performance without the model being broken (given things we've seen before).
That's not very different from using ccache. Claiming that there are no builds is simply not true.
> So for example if someone publishes a library, no new build step would ever be required for consumers of that library.
Does that require trusting compiled blobs from 3rd parties? That could make it trivial to inject backdoors.
So for example if someone publishes a library, no new build step would ever be required for consumers of that library.
Even with CI/CD there would be no build step because the very act of merging one's code into another codebase operates on canonical representations and so they never need to be regenerated.