Hi David,
Wonderful example. I'm afraid no-eager-blackholing also breaks the "no spooky action at a distance" rule. Since `x` is not used recursively, we should be able to pull it out of the `mfix` call, transforming the original to:
foo :: ST s Int
foo = do
ref <- newSTRef True
x <- readSTRef ref
mfix $ \res -> do
if x
then do
writeSTRef ref False
return $! res + 5 -- force the final result
else return 10
I believe this variant will produce <<loop>> with or without eager-blackholing, as it should. By this argument alone, I'd say the no-eager-blackholing breaks mfix axioms for strict-state.
This example is also interesting from a pure termination point of view: Moving things "out-of" mfix usually improves termination. In this case, the opposite is happening.
Strictly speaking, this is in violation of the mfix-axioms. But I doubt it's worth losing sleep over. I suggest we add this as an example in the value-recursion section on how eager-blackholing can change things.
Cheers,
-Levent.