modifyIORef lazy? (was Re: BLACKHOLE in heap profile)
Sat, 19 Apr 2003 12:29:13 +1200
Hal Daume III writes:
| but when i replace:
| modifyIORef r <E>
| v <- readIORef r
| writeIORef r $! <E>
| I no longer run into this heap problem and the program runs much
| more quickly.
When (f $! x) is evaluated, first x is forced to Weak Head Normal
Form, and then (f x) is evaluated.
In this case, (writeIORef r $! <E>) is evaluated early, thanks to the
strict sequencing of actions in the IO monad, so <E> is evaluated
You should get the same result with
modifyIORef r $! <E>
| even if I use (modifyIORef f (\x -> id $! <E> x)), which I thought
| would fix it, there is still a heap problem.
That's different, because the application of ($!) does not get caught
up in the sequencing of actions. In answer to the subject line,
modifyIORef updates a reference strictly, but the thing the reference
refers to may be a suspended computation.
In this case, after the modifyIORef the reference points to a
(\x -> id $! <E> x) the_thing_previously_pointed_to
and the evaluation hasn't yet reached the ($!).