[Haskell-cafe] Staged evaluation, names?

wren ng thornton wren at freegeek.org
Fri Jan 9 08:39:09 EST 2009

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,

More information about the Haskell-Cafe mailing list