Hi TH'ers, This weekend I just wrote my first "Hello World" in TH. Meta programming is great fun! While hacking away a number of ideas popped up in my head about ways of extending TH to make it even cooler. I realise this is not the first mail in that category, there seems to be an endless number of things one could possibly add to TH. Anyway, read as far as you like, it's a pretty long mail. Derving ======= Is would be nice to make the deriving mechanism programmable with Template Haskell. The problem is when the typechecker finds a deriving clause for something it doesn't recognise, where should it look? What we need is a way to register presence of a new deriving gizmo to GHC, a new language construct in Template Haskell. Let's call it 'addDeriving'. It would be something which could only be invoked on the toplevel of a module. What type should it have? Well since it's a language construct I don't know what return type it should have but it's argument type should be something like this: (String, Dec -> Q [Dec]). The first argument is the name we refer to in the deriving clause. For example ' ... deriving Fold'. Does it have to be upper case? I don't know but I don't think so. The second argument tells GHC how the deriving works. GHC supplies the data type declaration and gets a bunch of declarations back. Using this we could say (on the toplevel of a module): addDeriving ("Fold", deriveFold) Note that this would let us derive not only instances but new functions or even new data types. Mega Awsome! Splicing pragmas =============== It would be nice to be able to splice in compiler pragmas. For example if one writes a TH module for deriving folds and builds one would like to generate rules pragmas so that GHC can fuse these functions when they are used. Generating self-optimising code :). Concretely one would add a constructor to the Dec data type. Something like this: data Dec = ... | PragmaD Pragma data Pragma = RulePr String Phase [(String,Maybe Type)] Exp Exp | InlinePr String | NoInlinePr String | Specialize String Type data Phase = Always | Upto Int | From Int Perhaps the deprecated pragma also makes sense. The other pragmas doesn't seem to make sense here. This is ofcourse very GHC specific but so is TH.
From Meta Haskell to Meta X ===========================
Template Meta Haskell is a language which is a very nice meta language for Haskell. It has some really nice quotation syntax for creating abstract Haskell syntax using Haskell's concrete syntax. But we all know that Haskell is a great meta language for any language, not just for itself. It is in fact what Haskell does best if you ask me. So it would be nice if we could extend this quotation mechanism to work for any language. Here's a proposal for doing more or less that. It is very much inspired by a very similar functionality in SML/NJ. See: http://www.smlnj.org/doc/quote.html The idea is this: we want to generalise the Oxford brackets (i.e. [| |]) so that they are overloaded. Here's an example: id :: ObjectLang a => a id = [| \x -> x |] Since we in general want to generate new names a better type would perhaps be: id :: ObjectLang a => Q a The real advantage of having this is ofcourse when we use the splicing mechanism inside the quotation. Like this: mkLet :: ObjectLang a => a -> Q a mkLet body = [| let x = $body in x |] The tricky thing is how to handle this in the parser. In SML/NJ they translate the quotation syntax to the following data type: data Frag a = Quote String | AntiQuote a According to this scheme Oxford brackets would be translated into something of type [Frag a]. For example: formula a = [| $a == > A |] would be translated to formula a = [Quote " ", AntiQuote a, Quote " ==> A "] Fo far this is exactly SML/NJ modulo syntax and some names. My idea is that we stick in a little parser function in front of the list. This function should be appropriately overloaded. Say we add the following class: class ObjectLang a where parseOL :: [Frag a] -> Q a Then our example above would be translated into: formula a = parseOL [Quote " ", AntiQuote a, Quote " ==> A "] Jolly useful! Adding this mechanism to TH will probably mess up the parser pretty badly. But I still think it is worth thinking through. This extension could be rather useful after all. One thing to think of is what to do with other syntactic categories. In TH we have [d| |] for declarations, [p| |] for patterns and so forth. Should there be a fixed number of syntactic categories for all object languages? Hopefully not but how would you lift the restriction? A long mail. Thank you for reading it all to the end. I hope you got something out of it. If you're either Simon PJ och Tim S then please consider the implications of what I've suggested. It would be nice to know if any of this makes sense/is doable. Cheers and happy meta programming, /Josef