Skip to content

Interleave usage and strictness demands

Sebastian Graf requested to merge wip/refactor-demand into master

As outlined in #18903 (closed), interleaving usage and strictness demands not only means a more compact demand representation, but also allows us to express demands that we weren't easily able to express before.

Call demands are relative in the sense that a call demand Cn(cd) on g says "g is called n times. Whenever g is called, the result is used according to cd". Example from #18903 (closed):

h :: Int -> Int
h m =
  let g :: Int -> (Int,Int)
      g 1 = (m, 0)
      g n = (2 * n, 2 `div` n)
      {-# NOINLINE g #-}
  in case m of
    1 -> 0
    2 -> snd (g m)
    _ -> uncurry (+) (g m)

Without the interleaved representation, we would just get L for the strictness demand on g. Now we are able to express that whenever g is called, its second component is used strictly in denoting g by 1C1((1(U),S(U))). This would allow a subsequent Nested CPR to unbox the division, for example.

Now other advances in expressiveness like #18885 (closed) are possible.

Fixes #18903 (closed).

Edited by Simon Peyton Jones

Merge request reports