#ifdef considered harmful (was: DData)
Jan-Willem Maessen - Sun Labs East
Janwillem.Maessen at Sun.COM
Mon Apr 19 15:38:18 EDT 2004
Sven Panne wrote:
> Jan-Willem Maessen - Sun Labs East wrote:
>> [...] The actual problem is function arguments. GHC can't do
>> worker-wrapper unless a function is strict. Often we end up with
>> something like this:
>>
>> data Tree a = Branch !Int a (Tree a) (Tree a)
>>
>> lookfor :: Int -> Tree a -> Maybe a
>> lookfor Leaf key = Nothing
>> lookfor (Branch k v l r) key
>> | key==k = Just v
>> | key < k = lookfor l key
>> | otherwise = lookfor r key
>>
>> Here we don't use "key" in the first clause, so GHC isn't allowed to
>> unbox. Most of the uses of Int# that I've seen in library code have
>> been workarounds to this problem. [...]
>
>
> If that's the only concern, there is no real problem. One can do:
>
> a) Help GHC a bit by hand with something like
>
> lookfor Leaf key | key == key = Nothing
>
> or
>
> lookfor Leaf key = key `seq` Nothing
>
> Not very nice, but a "traditional" way of improving strictness.
And, of course, we need to remember to do it uniformly everywhere in
our program. Figuring out where to put these things isn't always
easy. And frankly, I'd love to stamp out the use of equality for
strictification once and for all.
> b) Use GHC's -O2 flag, enabling specialization over constructors, which
> is exactly what you're looking for, see the "Game Plan" comment at
> the beginning of
>
>
> http://cvs.haskell.org/cgi-bin/cvsweb.cgi/fptools/ghc/compiler/specialise/SpecConstr.lhs?rev=1.20&content-type=text/x-cvsweb-markup
I had a fascinating conversation with Simon P-J some years back on
exactly this subject. It's a lovely optimization. But (as you point
out) I need to do -ddump-simpl (and understand the results) to be sure
the compiler's done it for me. Tomorrow, the compiler could (for some
reason) decide not to do it anymore. It's all terribly fragile.
Fundamentally, the idea here is to give a library implementor another
tool to say what they mean. They can be assured of reasonable-looking
code that's still tuned to run like the blazes---with the confidence
of a types backing them up. They don't have to go crawling through
their code or the simplifier output a line at a time. Unboxed types
were designed with exactly that goal in mind. But they're not
portable. I'm suggesting a lightweight, simple wrapper which would be
portable. Perhaps that wrapper should even be named "Int#"!
> Using "-O2 -ddump-simpl" with your (slightly corrected) example, one
> can see that the Ints are indeed unboxed during recursion.
>
> Cheers,
> S.
>
More information about the Libraries
mailing list