Simon Marlow <marlowsd@gmail.com> writes:The right thing is to have a clean separation between runtimeimports and compile-time imports. Perhaps we just annotate some imports tosay they aren't needed at compile-time for running the TH code. but thenwe also need compile-time vs. runtime build-depends in our .cabal files,and so on.
Yes, I was just looking into this yesterday. We already have something
similar for plugins, though of course the TH story is much more
involved (in part because GHC has to compile haskell code, not just load
and run a pre-existing object file).Its a big project, but ultimately we do have to tackle it, because it's theright thing to do. Anyone interested in working on this? Maybe start anew proposal to flesh out the details.
Yeah, I'm going to at least try. Don't know where formal proposals go,
but what I've got so far (definitely subject to change!):
1. Add a separate package database like we have for plugins for TH
imports, defaulting to the normal package database when empty
2. Use the TH package db for code to be *run*, but resolve all
reifications etc. against the normal target scope.
3. Add {-# TH #-}-annotated imports to specify modules to import
compile-time code from (if a module *also* has definitions to be
reified, it needs to be imported twice)
3a. If a module has any {-# TH #-} imports, enforce that *all*
compile-time executed code is pulled in via {-# TH #-} imports.
3b. Optionally add a warning for TH-using code that doesn't use
{-# TH #-}, as the first start of a migration path to enforcing
compiletime/runtime separation across the ecosystem.
3c. Not sure what the specific difficulties are that require the
staging restrictions, but possibly annotating same-module
definitions with {-# TH -} might make this easier?
4. Teach cabal how to add packages to the TH database
4a. Not sure how all this works, but probably this is the place to
e.g. request the non-profiled version of a package if ghc is
non-profiled and the target code is profiled
5. Modify the build process of the cross-compiler to build a stage-2
compiler that builds code for the target *and* host (at least, enough
of the host to build BCOs), and runs that host-targeted code in the
interpreter.
5a. This will require some way to distinguish
stage-2-as-target-native-compiler VS stage-2-as-hybrid-compiler.