Pre-Proposal: Introspective Template Haskell

Edward Kmett ekmett at gmail.com
Wed Nov 11 19:21:04 UTC 2015


In practice I find that almost every piece of template-haskell code I've
written gets broken by something every other release of GHC, so it hasn't
exactly been a shining beacon of backwards compatibility thus far.

Invariably it is always missing _something_ that I need, and anything that
ties it to a more canonical form like this would be a very good thing.

I'd strongly support this move.

A sample just from my current working directory:

haskell> grep -r MIN_VERSION_template_haskell */src

bifunctors/src/Data/Bifunctor/TH/Internal.hs:#if
MIN_VERSION_template_haskell(2,10,0)

bifunctors/src/Data/Bifunctor/TH/Internal.hs:#if
MIN_VERSION_template_haskell(2,7,0)

bifunctors/src/Data/Bifunctor/TH/Internal.hs:#if
MIN_VERSION_template_haskell(2,10,0)

bifunctors/src/Data/Bifunctor/TH/Internal.hs:#if
MIN_VERSION_template_haskell(2,8,0)

bifunctors/src/Data/Bifunctor/TH/Internal.hs:#if
MIN_VERSION_template_haskell(2,8,0)

bifunctors/src/Data/Bifunctor/TH/Internal.hs:#if
MIN_VERSION_template_haskell(2,8,0)

bifunctors/src/Data/Bifunctor/TH.hs:#ifndef MIN_VERSION_template_haskell

bifunctors/src/Data/Bifunctor/TH.hs:#if __GLASGOW_HASKELL__ < 710 &&
MIN_VERSION_template_haskell(2,8,0)

bifunctors/src/Data/Bifunctor/TH.hs:#if MIN_VERSION_template_haskell(2,7,0)

bifunctors/src/Data/Bifunctor/TH.hs:#if MIN_VERSION_template_haskell(2,7,0)

bifunctors/src/Data/Bifunctor/TH.hs:#if MIN_VERSION_template_haskell(2,7,0)

bifunctors/src/Data/Bifunctor/TH.hs:#if MIN_VERSION_template_haskell(2,7,0)

bifunctors/src/Data/Bifunctor/TH.hs:#if MIN_VERSION_template_haskell(2,7,0)

bifunctors/src/Data/Bifunctor/TH.hs:# if __GLASGOW_HASKELL__ >= 710 ||
!(MIN_VERSION_template_haskell(2,8,0))

bifunctors/src/Data/Bifunctor/TH.hs:#if MIN_VERSION_template_haskell(2,7,0)

free/src/Control/Monad/Free/TH.hs:#if MIN_VERSION_template_haskell(2,10,0)

lens/src/Control/Lens/Internal/FieldTH.hs:#if
MIN_VERSION_template_haskell(2,8,0)

lens/src/Control/Lens/Internal/TH.hs:#ifndef MIN_VERSION_template_haskell

lens/src/Control/Lens/Internal/TH.hs:#define
MIN_VERSION_template_haskell(x,y,z) (defined(__GLASGOW_HASKELL__) &&
__GLASGOW_HASKELL__ >= 706)

lens/src/Control/Lens/Internal/TH.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Control/Lens/Plated.hs:#if !(MIN_VERSION_template_haskell(2,8,0))

lens/src/Control/Lens/TH.hs:#ifndef MIN_VERSION_template_haskell

lens/src/Control/Lens/TH.hs:#define MIN_VERSION_template_haskell(x,y,z)
(defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 706)

lens/src/Control/Lens/TH.hs:#if !(MIN_VERSION_template_haskell(2,7,0))

lens/src/Control/Lens/TH.hs:#if MIN_VERSION_template_haskell(2,10,0)

lens/src/Control/Lens/TH.hs:#if !(MIN_VERSION_template_haskell(2,7,0))

lens/src/Language/Haskell/TH/Lens.hs:#ifndef MIN_VERSION_template_haskell

lens/src/Language/Haskell/TH/Lens.hs:#define
MIN_VERSION_template_haskell(x,y,z) 1

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
!MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
!MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
!MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,8,0)

lens/src/Language/Haskell/TH/Lens.hs:#if
!MIN_VERSION_template_haskell(2,10,0)

lens/src/Language/Haskell/TH/Lens.hs:#if MIN_VERSION_template_haskell(2,9,0)

linear/src/Linear/V.hs:#ifdef MIN_VERSION_template_haskell

linear/src/Linear/V.hs:#if !(MIN_VERSION_reflection(1,3,0)) &&
defined(MIN_VERSION_template_haskell)

linear/src/Linear/V.hs:#if !(MIN_VERSION_reflection(1,3,0)) &&
defined(MIN_VERSION_template_haskell)

nats/src/Numeric/Natural.hs:#if defined(MIN_VERSION_hashable) ||
defined(MIN_VERSION_template_haskell)

nats/src/Numeric/Natural.hs:#ifdef MIN_VERSION_template_haskell

nats/src/Numeric/Natural.hs:#ifdef MIN_VERSION_template_haskell

tables/src/Data/Table.hs:#if MIN_VERSION_template_haskell(2,10,0)

tables/src/Data/Table.hs:#if MIN_VERSION_template_haskell(2,9,0)

tagged/src/Data/Proxy/TH.hs:#if MIN_VERSION_template_haskell(2,8,0)

tagged/src/Data/Proxy/TH.hs:#if MIN_VERSION_template_haskell(2,8,0)

tagged/src/Data/Proxy/TH.hs:#if MIN_VERSION_template_haskell(2,8,0)

tagged/src/Data/Proxy/TH.hs:#if MIN_VERSION_template_haskell(2,8,0)

On Wed, Nov 11, 2015 at 12:46 PM, Eric Seidel <eric at seidel.io> wrote:

> I think backwards-compatibility is still a potential issue, not because
> the pattern/type synonym layer seems implausible, but because I suspect
> people will begin to sidestep the compatibility layer and just use the
> GHC API (I certainly would). GHC is not shy about breaking
> backwards-compatibility between major releases, so it seems possible
> that this could extend to breaking TH. Missing features is not nearly as
> bad as breaking most clients of TH.
>
> But perhaps this isn't a very likely scenario. TH mostly exports
> datatypes for haskell syntax, smart constructors, and a few functions
> for looking up metadata. I doubt these pieces of GHC change very often,
> and when they do it's probably an extension rather than a breaking
> change. Someone with more historical knowledge of GHC could comment :)
>
> All in all, I like this idea a lot!
>
> Eric
>
> On Wed, Nov 11, 2015, at 08:26, Richard Eisenberg wrote:
> > Hi devs,
> >
> > There's a bunch of open tickets around Template Haskell. A great many of
> > them are attempts to make TH more like what's already in GHC. Of course,
> > when someone improves GHC, then TH also has to be updated. But this
> > doesn't always happen, leading to several of these tickets.
> >
> > I believe I have a solution to the problem: just eliminate Template
> > Haskell and provide direct access to GHC's internal structures. The idea
> > (still very sketchy; hence pre-proposal) is like this (numbered for easy
> > reference, but no order is implied):
> >
> > 1. TH quotes would remain. DsMeta would desugar quotes into Core code
> > that produces HsExprs. For example, [| 1 |] would have type (Q (LHsExpr
> > Name)). (Or perhaps (Q (LHsExpr RdrName)) if that works out better for
> > clients.)
> >
> > 2. TH splices would remain, working much as they do now. The expression
> > inside, say, an expression splice would have type (Q exp) where we can
> > satisfy the constraint (SpliceExpr exp). There would be instances for
> > (SpliceExpr (LHsExpr Name)) and (SpliceExpr (LHsExpr RdrName)) as well as
> > the non-located variants. Generalizing the type of expressions here
> > allows users not to worry about un-renaming when roundtripping between
> > quotes and splices.
> >
> > 3. Reification would remain, using an Info structure much like we have
> > now. Would we expose the real GHC TyCons as the result of reification? Or
> > is it better to give the users HsDecls? This would need to be fleshed
> > out.
> >
> > 4. Lifting would remain, doing the obvious thing.
> >
> > 5. The template-haskell package could even remain, as a
> > backward-compatibility shim. It would declare gobs of pattern synonyms
> > and type synonyms to wrap the new underlying interface. This re-imagined
> > template-haskell package would not need to be a boot library, and could
> > be upgraded separately from GHC. We could even maintain multiple versions
> > of the library so that TH clients wouldn't have to change their code when
> > GHC upgrades. Perhaps someday we could think about deprecating, if that's
> > the way the wind blows.
> >
> > So, the end result is a completely re-engineered TH, but I believe we
> > could keep full backward compatibility. (I have not considered Typed TH
> > in any depth yet. But my hope is that it's not too different from the
> > above.) And, we're left with a significantly lower maintenance burden,
> > especially if we eliminate template-haskell someday.
> >
> > And, tantalizingly, the flexibility in splices might allow us to splice
> > in *Core* code someday. Perhaps we could also reify Core code. Then
> > clients could write their own custom, domain-aware optimizations. Like
> > RULES on steroids. But that's all for the next phase. (Giving due credit,
> > this last bit is inspired by work David Christiansen is doing in Idris.)
> >
> > What's wrong with this idea? I feel like *something* has to be more
> > complicated than I've made it seem!
> >
> > Richard
> > _______________________________________________
> > ghc-devs mailing list
> > ghc-devs at haskell.org
> > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
> _______________________________________________
> ghc-devs mailing list
> ghc-devs at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-devs/attachments/20151111/ff274f4b/attachment-0001.html>


More information about the ghc-devs mailing list