18

Haskell supports mutually recursive let-bindings, which is great. Haskell doesn't support mutually recursive modules, which is sometimes terrible. I know that GHC has its .hs-boot mechanism, but I think that's a bit of a hack.

As far as I know, transparent support for mutually recursive modules should be relatively "simple", and it can be done exactly like mutually recursive let-bindings: instead of taking each separate module as a compilation unit, I would take every strongly connected component of the module dependency graph as a compilation unit.

Am I missing something here? Is there any non-trivial reason why Haskell doesn't support mutually recursive modules in this way?

  • 11
    Haskell does support mutually recursive modules. It's just ghc that doesn't implement them well. – augustss Jan 04 '13 at 05:00

1 Answers1

21

This 6-year-old feature request ticket contains a fair amount of discussion, which you may have already seen. The gist of it is that it's not entirely a simple change as far as GHC is concerned. A few specific issues raised:

  • GHC currently has a lot of baked-in assumptions about how modules are processed during compilation, and changing those assumptions significantly would vastly outweigh the benefits of transparent support for mutually recursive modules.

  • Lumping groups of modules together means they have to be compiled together, which means more recompilation and awkwardness with generating separate .hi and .o files.

  • Backward compatibility with existing builds that use hs-boot files.

  • You have the potential for mutually-recursive bindings that cross module boundaries in a mutually-recursive module group, which raises issues with anything that involves implicit, module-level scope (such as defaulting, and possibly type class instances).

  • And of course, the potential for unknown, unanticipated bugs, as with anything that alters long-standing assumptions in GHC. Even without massive changes to the compilation process, many things are currently assumed to be compiled on a per-module basis.

A lot of people would like to see this supported, but so far nobody has either produced a possible implementation or worked out a detailed, well-specified design that handles all the fiddly corner cases of the sort mentioned above.

C. A. McCann
  • 76,893
  • 19
  • 209
  • 302
  • 3
    If I ignore technical debt, backwards compatibility, and established code (which I lumped together as "trivial reasons" ;)), only one issue remains: modules are suddenly not so special anymore, which might cause problems with the type classes. It had crossed my mind, but I really wasn't sure if this would be a problem. Is it currently possible to import symbols, while hiding instances? If not, then an SCC of modules shouldn't be able to define/import conflicting instances anyway, not even with `.hs-boot`... –  Jan 04 '13 at 02:41
  • 5
    @Tinctorius: In that case, you missed another non-trivial reason, specifically that the people responsible for GHC don't consider those other reasons trivial. :P – C. A. McCann Jan 04 '13 at 02:47
  • And recompilation is indeed an awkward problem. So that's two issues when one would create a compiler from scratch. –  Jan 04 '13 at 11:16