Quasi quoting
Simon Peyton-Jones
simonpj at microsoft.com
Mon Feb 1 01:50:42 EST 2010
Dear GHC users
This email is to announce two proposed changes to GHC's quasi-quotation mechanism. For all I know, no one is using quasi-quotation (although it's a very cool feature, thanks to Geoff Mainland), but I didn't think I should take it for granted!
The current spec is here:
http://haskell.org/haskellwiki/Quasiquotation
http://www.haskell.org/ghc/docs/latest/html/users_guide/template-haskell.html#th-quasiquotation
A quasi-quote can appear as a (a) expression (b) pattern, and looks like this
[$pads| ...blah... |]
where 'pads' (of course any name will do) is a record of functions
data QuasiQuoter = QuasiQuoter {
quoteExp :: String -> Q Exp
quotePat :: String -> Q Pat
}
The idea is that GHC evaluates (pads "...blah..."), and splices in the resulting Exp (or Pat) just as if that's what the user wrote in the first place.
Kathleen Fisher has started to use this for her PADS system, and came up with two suggestions.
1. Allow quasi-quotes at the (top-level) declaration level, just like TH splices. So you could say, at top level
[$pads| ...blah... |]
and have it expand to a bunch of top level Haskell declarations. This seems like an unconditionally good idea. To support it we'd need to add a field to QuasiQuoter:
data QuasiQuoter = QuasiQuoter {
quoteExp :: String -> Q Exp
quotePat :: String -> Q Pat
quoteDec :: String -> Q [Dec]
}
but I don't think anyone will lose sleep over that.
2. Make the notation less noisy for the "customer". In particular, that '$' is scary, and redundant to boot. She would like to write
[pads| ...blah... |]
I can see the motivation here, but there are two reasons for caution.
(i) The Template Haskell quote forms [t| ... |] and [d| ... |] behave
rather differently.
(ii) If "[pads|" is a lexeme, then some list comprehensions become illegal, such
as [x|x<-xs,y<-ys]. But note that because of Template Haskell quotations,
a comprehension [t|t<-ts] is already broken, and similarly with 'd', 'e'.
So the proposed change will make things *more* uniform, by grabbing every
"[blah|" as lexeme.
For me (i) is the main issue. The differences are significant.
- A TH quote can appear only where an *expression* is expected
But a quasiquote can be an expression or pattern or (assuming (1)) declaration
- A TH quote has type (Q Typ) or (Q [Dec]) or (Q Exp)
But a quasiquote is run immediately and spliced in place of the quote
- A TH splice is run during type checking
But a quasiquote is run during renaming
Even given all that, I'm strongly inclined to follow Kathleen's suggestion:
- The differences are there all right, but in some ways the programmer thinks
the same way: [lang| blah |] switches to language 'lang'.
- Many users will never encounter the issue; they'll just say
[pads| blah |]
to wake up the PADS magic, and be oblivious to Template Haskell quotes
An alternative would be to have some other cue. Ones I've considered
- $[pads| ...|], but allowing the $ to be omitted on top-level declarations,
top level, just as it now can for TH splices.
- [pads:| ... |], with the colon distinguishing quasi-quoting from TH.
My gut feel is to go with [|pads| ... |]. Of course this'd be a change from the current syntax, but I think there are few enough users that they'll switch easily enough.
Any comments on any of this?
Simon
More information about the Glasgow-haskell-users
mailing list