[Haskell-cafe] Unused type-classes triggering a recompilation?

Brandon Allbery allbery.b at gmail.com
Wed Oct 18 17:55:04 UTC 2017

On Wed, Oct 18, 2017 at 1:43 PM, Saurabh Nanda <saurabhnanda at gmail.com>

> Because it is part of the external interface for dependencies of those
>> modules and therefore triggers both an API change (which here has no
>> effect) and an ABI change because internals of a module can leak out via
>> .hi file exposure for cross-module inlining. There is no way to guard
>> against that last, and avoiding it would usually be even more expensive
>> than just treating the entire .hi as a dependency that changed (the
>> dependency graph would *explode* if you had to track dependencies per
>> possible inlining).
>> And no, you do not want to defeat inlining, *especially* with lens.
>> Performance will utterly tank.
> I probably have not understood what you're saying. In LensClasses.hs if I
> simply add a new HasAddress class without defining an instance anywhere in
> the app, it triggers a re-compile. Is this changing the API / ABI in any
> way?

Yes, because when it is compiling the module containing that class, it
can't know that some program years down the road won't define an instance
for it, so it has to change the exposed interface. Beyond that, since we're
limited to file-level dependency handling (because you can't recompile only
the part of a source file that uses some dependency), compilers haven't
much choice but to recompile more than is necessary --- which is why things
work better when you split things into smaller files, but (as you also
noted) now computing the dependency graph becomes the slow part because
there are so many more dependencies to keep track of.

I suspect what you really want is a whole-program compiler. ghc is designed
for separate compilation, and this forces fundamental design choices in a
different direction than whole-program compilation does. jhc was
whole-program but development has halted and it was never complete enough
to handle e.g. lens.

This is not really ghc specific though, or haskell specific; show me any
language or build system that can do dependency handling at a level smaller
than a file. ghc does show it more clearly because of the cross-module
inlining bit, because it means the dependency footprint is much larger than
it looks --- but the performance without that inlining is abysmal.
(Languages like Javascript *do* avoid it, by effectively generating all
code 'on the fly' --- but that also imposes a fairly high overhead of its
own; the larger a project gets, the more obvious that overhead is.)

brandon s allbery kf8nh                               sine nomine associates
allbery.b at gmail.com                                  ballbery at sinenomine.net
unix, openafs, kerberos, infrastructure, xmonad        http://sinenomine.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20171018/eda8edc4/attachment.html>

More information about the Haskell-Cafe mailing list