<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Oct 18, 2017 at 1:43 PM, Saurabh Nanda <span dir="ltr"><<a href="mailto:saurabhnanda@gmail.com" target="_blank">saurabhnanda@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><span><div>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).<br></div></span><div><br></div><div>And no, you do not want to defeat inlining, *especially* with lens. Performance will utterly tank.</div></div></div></blockquote><div><br></div></span><div>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?</div></div></div></div></blockquote></div><div class="gmail_extra"><br></div>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.</div><div class="gmail_extra"><br></div><div class="gmail_extra">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.</div><div class="gmail_extra"><br></div><div class="gmail_extra">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.)<br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div>brandon s allbery kf8nh                               sine nomine associates</div><div><a href="mailto:allbery.b@gmail.com" target="_blank">allbery.b@gmail.com</a>                                  <a href="mailto:ballbery@sinenomine.net" target="_blank">ballbery@sinenomine.net</a></div><div>unix, openafs, kerberos, infrastructure, xmonad        <a href="http://sinenomine.net" target="_blank">http://sinenomine.net</a></div></div></div>
</div></div>