Right now, you must enable the TemplateHaskell extension to use (non-quasi) quotes, and TemplateHaskell is not supported by the stage 1 compiler. But there actually is no good reason why this should be the case: (non-quasi) quoting doesn't require any user-written code to be loaded up and run, so it should be doable by the stage 1 compiler. I propose adding a new extension, Quotes, which turns on JUST quotation (NOT quasiquoting) and works with the stage 1 compiler.
This will solve len's problem https://github.com/ekmett/lens/issues/496 where they want to rename some syntax using quotation, but don't want break compilation on a stage 1 compiler.
Minor point: we already have a language extension Opt_QuasiQuotes. Surely we don't need another!
Medium point: this change really only relates to building GHC itself, so it's fairly parochial. For example if we have [qq| blah |] in GHC itself, then to compile stage 2 we must have qq defined in some library that is compiled with stage 1; a boot library in other words. And the boot libraries are fairly limited.
Main thing: It does add complexity. If you write [qq| blah |] then:
In stage 1 we must find and dynamically link function qq, against the bootstrap compiler
In stage 2 we must find and dynamically link function qq, against the stage 1 compiler
Moreover, if HsSyn has changed, then function qq must change too.
And if you can manage all this version skew stuff, what's to stop us allowing all Template Haskell splices in stage 1? I thought it was obvious, but now I can't quite see it!
To be clear, I am NOT suggesting quasi-quotes be supported by this; just plain old brackets! (Apologies for the bad names; perhaps "expression quotation" is a more accurate name?) With plain quotes, we don't have to find and link qq with this complexity. See the diff that's been attached, which I know works and is not all that complicated.
Whether or not the change is parochial, I think it relates to more than just GHC; it applies to any platform where we can compile GHC, but dynamic code loading is not supported (i.e. no GHCi support). Now, you might wonder, "why would anyone need to use TH quotes, without any TH splices?" but Edward Kmett gives an example of one such case, where he wants to put his TH library code (no splices) in a main library, while still supporting platforms without GHCi, without macroing the business.
Unusual? Maybe. But someone wants it, and it doesn't seem too hard to give them, so let's do it!
If we don't like the language extension, we could alternate make TemplateHaskell not immediately error on stage 1 compilation, and just error when we actually reach a splice site.
Edward Z. Yangchanged title from Template Haskell quotes should work with stage 1 compiler to Template Haskell (non-quasi) quotes should work with stage 1 compiler
changed title from Template Haskell quotes should work with stage 1 compiler to Template Haskell (non-quasi) quotes should work with stage 1 compiler
On one hand I have a number of packages that provide TemplateHaskell convenience functions for users, lens being the go-to example. But on the other hand, I have a bunch of folks who maintain releases for my packages on platforms where only a stage1 compiler is available, Joachim Breitner and the Debian folks used to maintain patches and versions of my code that removed large chunks of the libraries to build on those platforms.
When i found out, I offered to support stage1 compilers myself more directly. This ensured a more uniform API, and that different distributions weren't crippling my code in different ways, making it so certain combinators or modules just weren't available on certain platforms.
But then we ran into an issue, we needed to generate names that linked to the right places within our code. So we manually construct all of our names ourselves, using the cabal-supplied version number or package key when needed:
Then we just don't use the TemplateHaskell extension ourselves, despite linking against the template-haskell package and everything is good enough for us to limp along.
I would love to eventually be able to drop this set of hoops, but I have few opinions on the best way to get there. That said, Edward's suggestion of making TemplateHaskell just bomb when you reach a splice site in stage1 rather than immediately would avoid introducing any new flags and sounds pretty simple.
Seems sensible to me, if we just piggyback on the TemplateHaskell extension. (I, too, don't like Quotes!) If Phab is to be believed that almost all the code changes there are code movement and not code changes, it does look indeed very simple to implement.
Sorry for being a little late to the discussion. Ideally, I would prefer that a stage1 compiler would try and go ahead with compiling template haskell, until it figures it can't. Motivation being: when ever I find time to hack on out-of-process-template-haskell (effectively trying to bring over luites th approach from ghcjs), I have to inject lots of ifdefs into the ghc code to even get ghc to the point where it starts to complain that it can't compile the splice instead of refusing to even try it right from the start.
I haven't had much time to work on it throughout the last half year but would love to continue with it. I'll leave some of the relevant links here:
(c) everything else that does not include (a) or (b).
where (c) should be fine to compile on the host, (b) could probably be also compiled on the host if all the target intrinsic information is taken care of. (a) is going to be interesting, as at least with the out-of-process-th appraoch, you would be running the code on a device that might not have the same environment. Such that thinks like looking up git revisions would have to fail.