Core visible conditional compilation/static definition/code selection based upon static key values
currently the way we write haskell code to handle multiple platforms or configurations use the C preprocessor (CPP) in traditional mode.
there are several challenges with this
not actually designed for haskell code
no compiler support for checking the syntax / name / type well-formedness of each alternative code fragment under the associated environment assumptions.
Abstractly, CPP uses a mapping from Names to Maybe (Either String Integer) or something to that effect.
theres two ways we could then treat a "HPP" design:
- just like CPP traditional mode, its just splicing tokens together.
a) One implication of this design choice would be that to be able to check/ parse the different combinations of compilation, you'd need to be able to enumerate the set of maps of key value pairs of interest, and then you'd roughly want to have each Module be actually a
Map (Map String (Maybe (Either String Integer))) Module)
this would have some pretty obvious code blowup issues, at least if you wanted to full on type check each combination in full.
- only allow "HPP" to work on valid syntactic units, eg expressions, right hand sides, patterns, top level definition, etc, and provide a magic primop or several that would look roughly like
NOTE: it could also just be at the Haskell post type inference phase, not necessarily at core level
DefinitionDispatchTermLevel :: [(Map String (Maybe (Either String Integer)) , CoreTerm)] -> --- set of all #if/else/ifdef etc conditionals? Map (String) (Maybe (Either String Integer)) -> -- actual CPP flag combination used CoreTerm -> --- actual term ghc / optimizer works with and manipulates CoreTerm
this sketched out constructor representation overlooks a few things, eg the ability to do interval predicates and various boolean algebra operations, which WOULD be expressible in a fully fleshed out approch to this, but i'm elliding to keep simple.
i think approach (1) or something like it would have the benefit of mostly working "today" wrt how we use CPP, and checking/coverage could be done via some package level or module level enumeration of cpp value mappings that you wnat to be checked or even generated
approach (2) adds a funny looking operation to core/haskell terms/types representation where you could carry around "alternative expressions" plus the "selected expression". and thus you could do some amount of syntax/type checking for those altnerative platforms?
either way, this is just me jotting down some thoughts on this because its been discussed on and off for a while now as an eventual nice to have for ghc.
Also quite a complicated design space! :)