[Haskell-cafe] Shared thunk optimization. Looking to solidify my understanding

Daniel Fischer daniel.is.fischer at web.de
Wed Sep 22 11:48:31 EDT 2010


On Wednesday 22 September 2010 17:10:06, David Sankel wrote:
> The following code (full code available here[1], example taken from
> comments here[2]),
>
> const' = \a _ -> a
>
> test1 c = let a = const' (nthPrime 100000)
>           in (a c, a c)
>
> test2 c = let a = \_ -> (nthPrime 100000)
>           in (a c, a c)
>
>
>  in a ghci session (with :set +s):
>
> *Primes> test1 1
> (9592,9592)
> (0.89 secs, 106657468 bytes)
> *Primes> test2 1
> (9592,9592)
> (1.80 secs, 213077068 bytes)
>
>
> test1, although denotationally equivalent to test2 runs about twice as
> fast.
>
> My questions are:
>
>    - What is the optimization that test1 is taking advantage of called?

Sharing. test1 computes nthPrime 100000 only once, test2 twice.
Note that when compiled with optimisations, test1 and test2 give exactly 
the same core.

>    - Is said optimization required to conform to the Haskell98 standard?
> If so, where is it stated?

No, it's not required. Unconditional sharing may be bad, so it would be 
unwise to demand sharing.

>    - Could someone explain or point to a precise explanation of this
>    optimization? If I'm doing an operational reduction by hand on paper,
> how would I take account for this optimization?

More or less

test1 c =
    let v = nthPrime 100000
        a = const' v
    in (a c, a c)

You (the compiler) give(s) a name to a value, when the value is referred to 
via that name, it's not recalculated (it's calculated on first demand).

>
> Thanks,
>
> David
>
> [1] http://hpaste.org/40033/operational_semantics
> [2] http://conal.net/blog/posts/lazier-functional-programming-part-2/



More information about the Haskell-Cafe mailing list