4

Note that:

  • Exp in template-haskell corresponds to HsExpr in the GHC AST
  • Type in template-haskell corresponds to HsType in the GHC AST
  • Dec in template-haskell corresponds to HsDecl in the GHC AST

However, there is one set of constructors missing in the template-haskell types: those pertaining to TH splices and quasiquotes. For example, why doesn't Exp have a constructor of the following form?

SpliceE :: Exp -> Exp

I've stumbled across this here too. I'd like to know if there is something fundamental about this, or there is just extra work to be done fleshing out the TH types? I suspect the issue is that with this, one could send TH into an infinite loop - have a splice generating another splice, and so on. That said, there are already many ways of making the GHC diverge... :)


My use case is wanting to have an extra TH stage (so that I can lift a value to the type level - in the parent stage it is a value, but I can generate code with that value lifted to the type level for the child stage using promote)

Alec
  • 31,829
  • 7
  • 67
  • 114
  • 1
    I doubt there's a more profound reason than "TH isn't implemented as a multi-pass thingy", interesting question anyway though. – Cubic Jan 28 '18 at 18:51
  • @Cubic Is that true though? I would've thought that stages would've solved that problem... Isn't GHC already doing a form of this for declarations? [Gist example.](https://gist.github.com/harpocrates/cfaf8c45092e17239d7cdcc172e90975) – Alec Jan 28 '18 at 19:29
  • @Alec, your example is not treated by GHC using multiple passes. Rather, GHC cuts up every source file in minimal groups of declarations (but mutually recursive groups cannot be split up) and processes each of these separately. This is also why TH code can only reference declarations higher in the file, outside the current mutually recursive group. – Dominique Devriese Jan 28 '18 at 20:10
  • @DominiqueDevriese wrong choice of words regarding “multiple pass”. Words aside, is this different from what I’m asking about though? – Alec Jan 28 '18 at 20:28
  • Err.. yes, AIUI. I think Cubic was talking about a scenario where TH would first be executed at stage -2 to generate new stage -1 TH code, which would subsequently be executed to generate actual stage 0 code. So the TH engine would need to be run twice, the second time on the output of the first stage. This kind of multi-passness probably has all sorts of practical design consequences that I don't think TH has currently incorporated... – Dominique Devriese Jan 29 '18 at 11:23

0 Answers0