Re-think how to supply wired-in Names to GHC
GHC's treatment of wired-in names means that libraries containing wired-in names, such as ghc-internal
and (currently) template-haskell
need to be compiled with -this-unit-id
. This is in order for the libraries' unit-id to be known and fixed, so that GHC can guess the symbol name to link against prior to even seeing its definition site (late binding).
Alas, -this-unit-id
prevents to reinstall libraries, because there can only ever be a single library under a given unit-id lest we get linker errors.
Reinstalling libraries provides ample motivation to try to find ways to wire in names that don't need -this-unit-id
. Let us collect independent proposals here to work around that:
-
Instead of hard-coding what is effectively a symbol table in
Builtin.Names.TH
, we could maintain the symbol table in a file, kind-of what we do for platform constants inGHC.Platform.Constants.parseConstantsHeader
. Then every invokation of GHC would need to know a symbol table of the libraries it is supposed to link against. Now every library would be reinstallable, evenghc-internal
, provided its exported names are compatible with the GHC that is supposed to link them. It is even possible to provide the symbol table (just a text file part of the source distribution) prior to compiling the library, to achieve late binding.(All this is not unlike .hs-boot files or backpack module signature. Alas, .hs-boot files do not work across libraries (I think?) and backpack does not compile a module unless all its dependencies have been instantiated (I think?), ruling out late binding. Also it is quite a heavy hammer.)
-
Instead of maintaining the symbol table in (1) explicitly as a text file, we could instead do so declaratively, in code, by coming up with some annotation mechanism. For example, we could annotate the definition of
foldr
with{-# ANN builtin "foldr" #-}
(modulo unimportant syntax) and then write out thebuiltin
s a library defines in the interface file. Advantage: declaration in code. Disadvantage: No late binding.
Feel free to add other suggestions.
The hope is that we can reinstall even ghc-internal
afterwards, as long as the ghc-internal
to link against provides the appropriate symbols and is actually compilable with GHC.
Reasons why we should not change the way we wire in Names:
- There is a lot of existing code that we would need to change. In particular, the RTS hard codes some symbol names and it's far harder to parameterise those. Furthermore, lots of code in the compiler depend on the wired-in names as pure, top-level definitions. It would be quite hard to parameterise all of this code over a dynamic symbol table.