
roconnor@theorem.ca wrote:
On Tue, 16 Jun 2009, Neil Mitchell wrote:
What is the need for swap' ? Things like foldl' solve space leaks, what does swap' solve? I fully agree on the addition of swap.
I'm not sure what swap' solves. I just think it has a pretty symmetry to it. I presume one of these pro-strict-swap people can come up with an example of where swap' solves a problem.
Sure. f (x, y) z = let !t = x+z in (t, y) bar1 xs = foldl' ((swap' .) . f) (0, 0) xs bar2 xs = foldl' ((swap .) . f) (0, 0) xs Prelude Swap> bar1 [0..1000000] (250000000000,250000500000) Prelude Swap> bar2 [0..1000000] (*** Exception: stack overflow Actually, "swap" works fairly well most of the time, because in addition to its laziness, ghc's garbage collector does short-cut evaluation of record selectors. So if the code just builds up a chain of swaps, GC will compress that chain very nicely. But I still prefer the strict version. Bertram P.S. I'd problably write your example as foo x [] = (x, 0) foo x [y] = (0, x + y) foo x (y:z:xs) = let !t = x + y + z in foo t xs or, if I wanted to do something fancy, foo x xs = r where (c, d, r) = go x xs (c, d) go x [] r = (x, 0, r) go x (y:ys) r = let !z = x + y; !r' = swap' r in go z ys r' Compiled, both versions end up about 2 times faster than foo x [] = (x, 0) foo x (y:xs) = let !z = x + y in swap (foo z xs) on foo 0 [0..1000000].