Skip to content

-XStrict does not use call-by-value

Consider

{-# OPTIONS_GHC -O2 -fforce-recomp #-}
{-# LANGUAGE Strict #-}

module Lib where

foldr' _ z []     = z
foldr' f z (x:xs) = f x (foldr' f z xs)

this produces the following -ddump-prep output:

foldr'
  = \ @ t_atW @ t1_au0 ds_sBM z_sBN ds1_sBO ->
      case ds_sBM of ds2_sBP { __DEFAULT ->
      case z_sBN of z1_sBQ { __DEFAULT ->
      case ds1_sBO of {
        [] -> z1_sBQ;
        : x_sBS xs_sBT ->
          let { sat_sBU = foldr' ds2_sBP z1_sBQ xs_sBT } in
          ds2_sBP x_sBS sat_sBU
      }
      }
      }

Note that it uses call-by-need for the foldr' f z xs argument. I think many programs using -XStrict would be much stricter if they used call-by-value, but the current semantics of -XStrict seems to be concerned about patterns and data types only.

An interesting side note: If I write foldr' instead as

foldr' _ z []     = z
foldr' f z (x:xs) = let z' = foldr' f z xs in f x z'

I get the desired program

foldr'
  = \ @ t_auk @ t1_auo ds_sC4 z_sC5 ds1_sC6 ->
      case ds_sC4 of ds2_sC7 { __DEFAULT ->
      case ds1_sC6 of {
        [] -> z_sC5;
        : x_sC9 xs_sCa ->
          case foldr' ds2_sC7 z_sC5 xs_sCa of z'_sCb { __DEFAULT ->
          ds2_sC7 x_sC9 z'_sCb
          }
      }
      }

Which doesn't make a lot of sense to me.

Probably needs a GHC proposal to fix.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information