[Haskell-cafe] Plug space leak with seq. How?

Daniel Fischer daniel.is.fischer at googlemail.com
Thu Jun 9 19:38:01 CEST 2011


On Thursday 09 June 2011, 18:41:40, Alexey Khudyakov wrote:
> On 09.06.2011 20:09, Yves Parès wrote:
> > Is it not:
> >  > noLeak :: State Int ()
> >  > noLeak = do
> >  > 
> >  >   a <- get
> > 
> > *>* *let a' = (a + 1)
> > 
> >  >   a' `seq` put a'*
> >  >   noLeak
> > 
> > ??
> 
> Indeed. Now I understand. It didn't work for me earlier because of
> different behavior of 'forever' in ghci and compiled code.
> 
> This function leaks in ghci and do not in compiled code without
> optimizations (with optimizations GHC is smart enough  to make
> everything strict).
> 
>  > noLeak = forever $ do { a <- get; let a' = a+1; a' `seq` put a' }
> 
> Function with explicit recursion do not leak in both cases.
> 
>  > noLeak = do { a <- get; let a' = a+1; a' `seq` put a'; noLeak }
> 
> What causes this difference?


forever a   = a >> forever a

doesn't tie to itself without optimisations, so my guess is that it gets 
expanded when you run/eval/execState it in ghci, building the thunk

a >> a >> a >> a >> ...

If you define

forever' a = let a' = a >> a' in a'

the variant using forever' runs in constant space in ghci.
This, like the explicit recursion, builds a cyclic structure, hence avoids 
the leak.



More information about the Haskell-Cafe mailing list