| 10 years ago, I commented on the Rust issue for "Incremental recompilation", where it was suggested that Rust could at least adopt Haskell GHC's model of incrementality, which is currently file-level: https://github.com/rust-lang/rust/issues/2369#issuecomment-1... This would already help a lot. I recommend anybody who's interested in incremental recompilation to read what GHC does, because the effort to achieve that is relatively low. Of course there's always desire for more: GHC currently needs to parse+typecheck+codegen a file before it can process other files that import it. Codegen is slow. Thus, there's currently demand split compilation into "stages", so that the next file can be typechecked after its imports have been just typechecked (not codegenned). I would also enjoy if recompilation avoidance were to happen at the function level, not the file level. Macro systems are a key language feature that can destroy incremental recompilation. In theory, Haskell is well set up for that, as its macro system (TemplateHaskell) is fully AST based and _theoretically_ could distinguish "fully pure" macros from side-effectful macros (such as splicing the current git commit in as a string literal). But the recompilation avoidance system does not currently exploit such differences. |
From what I see in Haskell files are the unit of compilation, and that's what allows incremental compilation to be file based (because it's really unit-of-compilation based)
I can see you can have circular dependencies between files with the `{-# SOURCE #-}` pragma, but I don't see documentation about how that affects incremental compilation.
A couple of issues I see with doing this in Rust are:
- in Rust the unit of compilaion is a crate, which can contain many fils/modules with circular imports, which is much more coarser than what can be done in Haskell.
- in Rust downstream crates can depend on function bodies upstream for running compile time functions; as such the crate/module interface is not enough to gate recompilation, but at the same time including all function bodies will also not give the wanted benefits. This is solvable but likely requires more work than what was done in Haskell.
In general you cannot take a language approach and blanket applying it to another one without considering their different quirks, which is likely why your proposal didn't get much attention. Or am I missing something that would make it easier to apply Haskell approach here?