Staged evaluation, names?

Dear Cafe, Every now and then I find myself in the position where I'd like to define some hairy value as a CAF instead of a literal, but I'd like for it to be fully evaluated at compile-time rather than postponed until runtime. It'd be possible to bludgeon the CPP into doing this, but it seems easier to use an autocannon like Template Haskell to swat this fly. This seems like a common thing for folks to want but the TH documentation targets much higher-hanging fruit, which actually made it harder to figure out how to do something this basic (which would have been transparent with MetaML/MetaOCaml-like syntax). I've figured it out and circumvented the gotchas, and I was thinking of releasing the code as a counterpoint to all the very-high level TH tutorials. The question for y'all is what should I call it? I've been calling the template-function qaf (for Compiled Applicative Form ;) and the type class with that function would be the only thing in the package, but I'm not sure where QAF.hs should be in the module hierarchy. Thoughts? -- Live well, ~wren

wren ng thornton schrieb:
Every now and then I find myself in the position where I'd like to define some hairy value as a CAF instead of a literal, but I'd like for it to be fully evaluated at compile-time rather than postponed until runtime. It'd be possible to bludgeon the CPP into doing this, but it seems easier to use an autocannon like Template Haskell to swat this fly.
Is it really necessary to use CPP or TemplateHaskell for this kind of optimization? Can a pragma help? Maybe {-# INLINE #-} ?

Henning Thielemann wrote:
wren ng thornton schrieb:
Every now and then I find myself in the position where I'd like to define some hairy value as a CAF instead of a literal, but I'd like for it to be fully evaluated at compile-time rather than postponed until runtime. It'd be possible to bludgeon the CPP into doing this, but it seems easier to use an autocannon like Template Haskell to swat this fly.
Is it really necessary to use CPP or TemplateHaskell for this kind of optimization? Can a pragma help? Maybe {-# INLINE #-} ?
Inlining the CAF will only copy the CAF definition to all the use sites, potentially increasing the work done at runtime. Inlining other functions or using GHC.Exts.inline liberally in the CAF will potentially blow up the code size, and while GHC may be so kind as to reduce the CAF at compile time, often times it doesn't.[1] The goal I have in mind is a very simple kind of metaprogramming. Consider for instance that you have a function which computes some arcane value. The results of this function are used in many places in inner loops of your program. You know that this arcane value is constant, but it would be troublesome to actually write it as a literal. If you did write it as a literal, then GHC could crank the optimizations on your inner loops, removing dead code and the like. These optimizations are often more important than the one-time cost of evaluating the arcane value and memoizing it (though that's wasted effort too). One example of where you'd like this sort of staged evaluation is to pre-compile textures and masks for graphics. You could compile the bits yourself and ship them with the code, or you could tell the compiler to generate them when it compiles the program. Another example is for architecture dependent bit-twiddling where you'd usually use a bunch of CPP to choose different implementations depending on endianness, word size, etc. It's not *that* common a problem, but it's come up often enough to pique my interest in trying out some TH. And it seems different enough from what most folks use TH for, so I thought I'd share. The only real solution I see other than TH or CPP would be if we had a JIT compiler, though I could still imagine cases where the staged version is better. [1] With good reason. It would be a bad idea to force many CAFs (e.g. lists of all Fibonacci numbers, or all primes), and deciding whether evaluation would finish is a pesky problem. Hence the need for a linguistic of metalinguistic way of telling the compiler it's okay. -- Live well, ~wren

On Thu, Jan 8, 2009 at 5:25 AM, wren ng thornton
The question for y'all is what should I call it? I've been calling the template-function qaf (for Compiled Applicative Form ;) and the type class with that function would be the only thing in the package, but I'm not sure where QAF.hs should be in the module hierarchy. Thoughts?
Isn't Lift[1] already the right class for this? class Lift t where lift :: t -> Q Exp [1] http://haskell.org/ghc/docs/latest/html/libraries/template-haskell/Language-...

Andrea Vezzosi wrote:
On Thu, Jan 8, 2009 at 5:25 AM, wren ng thornton
wrote: The question for y'all is what should I call it? I've been calling the template-function qaf (for Compiled Applicative Form ;) and the type class with that function would be the only thing in the package, but I'm not sure where QAF.hs should be in the module hierarchy. Thoughts?
Isn't Lift[1] already the right class for this?
class Lift t where lift :: t -> Q Exp
[1] http://haskell.org/ghc/docs/latest/html/libraries/template-haskell/Language-...
I don't see any documentation there to say what it does, so I'm not sure. (A common problem with TH, unfortunately.) -- Live well, ~wren

wren ng thornton wrote:
Andrea Vezzosi wrote:
On Thu, Jan 8, 2009 at 5:25 AM, wren ng thornton
wrote: The question for y'all is what should I call it? I've been calling the template-function qaf (for Compiled Applicative Form ;) and the type class with that function would be the only thing in the package, but I'm not sure where QAF.hs should be in the module hierarchy. Thoughts?
Isn't Lift[1] already the right class for this?
class Lift t where lift :: t -> Q Exp
[1] http://haskell.org/ghc/docs/latest/html/libraries/template-haskell/Language-...
I don't see any documentation there to say what it does, so I'm not sure. (A common problem with TH, unfortunately.)
After hunting down the source code, yes it looks like Lift does the same thing as my code. (Though the Int instance looks like it's more liberal since it doesn't restrict the ExpQ to being an Int.) It'd be nice if the TH API had better documentation... -- Live well, ~wren
participants (3)
-
Andrea Vezzosi
-
Henning Thielemann
-
wren ng thornton