
Hi
* As you say, if 'retry' was inlined, all would be fine. But what if 'retry' was big? Then we'd get lots of code duplication, in exchange for fewer tests.
* Presumably it's not inlined because it's over the inline size threshold. (You did use -O?)
I used -O2. I also added {-# INLINE #-} pragmas to both begin1 and begin2. In this case, I know that after inlining the let expression things will merge and become smaller afterwards (although can't see any reasonable way the compiler could know this). I realise that there is a limit on the size of inlining, and I can reduce the perceived cost of inlining begin1/begin2 with pragmas. However, once they have been inlined into a local let expression, it doesn't seem like there is much I can do to persuade the compiler to inline the let binding. I'm thinking of a situation something like: {-# INLINE foo #-} foo = large bar x = if x then res else res where res = foo By putting an INLINE on foo I am able to persuade it to be inlined into the binding of bar, but I can't then persuade it to be inlined at the let expression. (I tried to come up with a small example representing this situation, but the original begin1/begin2 example is as short as I can get)
* The 'state' argument is just there to make sure that 'retry' is a *function* not a *thunk*, to avoid the overheads of unnecessary thunk update.
OK. That seems perfectly reasonable. Does the introduction of the state argument either remove the inline annotation, or substantially increase the cost of inlining the let binding? Otherwise, I don't think its relevant to my particular case. Thanks Neil