Re: a compiled program is slower than byte code

2011-02-09 Thread Simon Marlow

On 09/02/2011 04:35, Kazu Yamamoto (山本和彦) wrote:

Hello Simon,


$ ghc-nightly2 ./kazu.hs -O2 -fforce-recomp; time ./kazu
[1 of 1] Compiling Main ( kazu.hs, kazu.o )
Linking kazu ...
4.17s real   4.16s user   0.01s system   99% ./kazu


OK. I ran it on 32bit Linux.

6.12.3  runghc   -- 2.22s user 0.40s system 96% cpu 2.724 total
 ghc  -- 1.96s user 0.14s system 97% cpu 2.151 total
 ghc -O   -- 2.18s user 0.10s system 97% cpu 2.333 total
 ghc -O2  -- 2.27s user 0.07s system 97% cpu 2.393 total

ghc-7.0 runghc   -- 3.43s user 0.35s system 97% cpu 3.861 total
 ghc  -- 5.11s user 0.07s system 97% cpu 5.299 total
 ghc -O   -- 5.38s user 0.03s system 97% cpu 5.534 total
 ghc -O2  -- 5.54s user 0.10s system 97% cpu 5.783 total


Thanks, I do see the problem now (I was inadvertently running the 
compiled code with runghc, because I used runghc foo.hs 
-fforce-recomp, which doesn't do what I thought it did).


I created a ticket: http://hackage.haskell.org/trac/ghc/ticket/4951

I think the difference between interpreted and compiled is due to
http://hackage.haskell.org/trac/ghc/ticket/917.  What I'm more worried 
about is the slowdown in pre-7.0.2 relative to other versions.




HEAD is more than twice as fast on this program.  Fusion not working,
perhaps?


Here is the results of ghc -O -ddump-simpl-stats:

ghc-7.0:

19 RuleFired
 6 ++
 2=#
 1 fold/build
 5 foldr/app
 1 foldr/augment
 1 foldr/single
 1 map
 1 unpack
 1 unpack-list

6.12.3:

25 RuleFired
 6 ++
 2=#
 3 fold/build
 6 foldr/app
 1 foldr/augment
 1 map
 2 repeat
 2 take
 1 unpack
 1 unpack-list


My stats look very different.

6 RuleFired
1 ++
2 =#
1 foldr/app
1 unpack
1 unpack-list

Are your libraries compiled with -O2?

Cheers,
Simon

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: a compiled program is slower than byte code

2011-02-09 Thread 山本和彦
Hello,

 My stats look very different.
 
 6 RuleFired
 1 ++
 2 =#
 1 foldr/app
 1 unpack
 1 unpack-list
 
 Are your libraries compiled with -O2?

I don't know. How can I check?

I just installed ghc-7.0 by perl boot; configure; make; make install.

--Kazu

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Deriviable type classes

2011-02-09 Thread Simon Peyton-Jones
Friends

Just a heads-up.  Pedro is working on implementing Generic Defaults, as 
described in his Haskell Symposium 2010 paper 
www.dreixel.net/research/pdf/gdmh_nocolor.pdf

It will replace (and improve on) the Derivable type classes stuff in GHC at 
the moment, which was originally presented in a paper of that title that Ralf 
and I wrote in the 2000 Haskell workshop 
http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm.

The Derivable type class extension is barely used, I believe, and isn't even 
documented in the manual.  So I propose to switch from one to the other, rather 
than to try to support both.  This change will happen in GHC 7.2 or 7.4, 
depending on when Pedro is done.

Please yell if you are a secret user of derivable type classes, so this change 
would discombobulate you.

Simon


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Deriviable type classes

2011-02-09 Thread José Pedro Magalhães
Hi,

2011/2/9 Simon Peyton-Jones simo...@microsoft.com

 Friends

 Just a heads-up.  Pedro is working on implementing Generic Defaults, as
 described in his Haskell Symposium 2010 paper
 www.dreixel.net/research/pdf/gdmh_nocolor.pdf

 It will replace (and improve on) the Derivable type classes stuff in GHC
 at the moment, which was originally presented in a paper of that title that
 Ralf and I wrote in the 2000 Haskell workshop
 http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm.

 The Derivable type class extension is barely used, I believe, and isn't
 even documented in the manual.


Isn't it this?:
http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html

But anyway, I can't remember seeing any use of it.


Cheers,
Pedro
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Deriviable type classes

2011-02-09 Thread Simon Peyton-Jones
The Derivable type class extension is barely used, I believe, and isn't even 
documented in the manual.

Isn't it this?: 
http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html

Oh yes, silly me.  It is documented!

Simon

From: José Pedro Magalhães [mailto:j...@cs.uu.nl]
Sent: 09 February 2011 12:20
To: Simon Peyton-Jones
Cc: GHC users
Subject: Re: Deriviable type classes

Hi,
2011/2/9 Simon Peyton-Jones 
simo...@microsoft.commailto:simo...@microsoft.com
Friends

Just a heads-up.  Pedro is working on implementing Generic Defaults, as 
described in his Haskell Symposium 2010 paper 
www.dreixel.net/research/pdf/gdmh_nocolor.pdfhttp://www.dreixel.net/research/pdf/gdmh_nocolor.pdf

It will replace (and improve on) the Derivable type classes stuff in GHC at 
the moment, which was originally presented in a paper of that title that Ralf 
and I wrote in the 2000 Haskell workshop 
http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm.

The Derivable type class extension is barely used, I believe, and isn't even 
documented in the manual.

Isn't it this?: 
http://www.haskell.org/ghc/docs/latest/html/users_guide/generic-classes.html

But anyway, I can't remember seeing any use of it.


Cheers,
Pedro
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Deriviable type classes

2011-02-09 Thread Sean Leather
2011/2/9 Simon Peyton-Jones:

 Friends

 Just a heads-up.  Pedro is working on implementing Generic Defaults, as
 described in his Haskell Symposium 2010 paper
 www.dreixel.net/research/pdf/gdmh_nocolor.pdf

 It will replace (and improve on) the Derivable type classes stuff in GHC
 at the moment, which was originally presented in a paper of that title that
 Ralf and I wrote in the 2000 Haskell workshop
 http://research.microsoft.com/en-us/um/people/simonpj/papers/derive.htm.

 The Derivable type class extension is barely used, I believe, and isn't
 even documented in the manual.  So I propose to switch from one to the
 other, rather than to try to support both.  This change will happen in GHC
 7.2 or 7.4, depending on when Pedro is done.

 Please yell if you are a secret user of derivable type classes, so this
 change would discombobulate you.


The only time I came across a use of it was in James Cheney's FreshLib [1].
I don't know if the latest version still uses it, though. There was also
this bug [2] that prevented FreshLib from being compiled, but that is
apparently fixed now.

[1] http://homepages.inf.ed.ac.uk/jcheney/programs/freshlib/
[2] http://hackage.haskell.org/trac/ghc/ticket/2824

Regards,
Sean
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


my RULES don't fire

2011-02-09 Thread Sebastian Fischer
Hello,

I want to use the RULES pragma and cannot get my rules to fire. Here is a
simplified example of what I'm trying.

I define my own version of foldMap for lists:

fold :: Monoid m = (a - m) - [a] - m
fold f = foldr mappend mempty . map f
-- alternative, trying to avoid interference with foldr/build fusion
-- fold _ [] = mempty
-- fold f (x:xs) = f x `mappend` fold f xs
{-# NOINLINE fold #-}

I try using a NOINLINE pragma to make the firing of my rules (which involve
fold) more robust. But they don't fire with or without NOINLINE. Also the
uncommented version does not make a difference.

I also define a function that creates a singleton list:

single :: a - [a]
single x = [x]
{-# NOINLINE single #-}

Now I want to replace calls of `fold f . g single` (or eta-expanded versions
of this) by `g f` using the following rules:

{-# RULES
  monoid fusion pointfree
forall f (g :: forall m . Monoid m = (a - m) - b - m) .
  fold f . g single = g f;

  monoid fusion pointed, general
forall f (g :: forall m . Monoid m = (a - m) - b - m) b .
  fold f (g single b) = g f b;

  monoid fusion pointed, for lists
forall f (g :: forall m . Monoid m = (a - m) - [a] - m) xs .
  fold f (g single xs) = g f xs;
  #-}

The variations of type signatures (including no signatures at all) for the
pattern variables that I tried did not change anything for the better.

I wrote the third rule only because the second gives a warning that I don't
quite understand:

Warning: Forall'd type variable b is not bound in RULE lhs
   fold @ m @ a $dMonoid f (g @ [a] $dMonoid (single @ a) b)

I try out the rules using the following function that takes the role of `g`
in the rules:

idGen :: Monoid m = (a - m) - [a] - m
idGen _ [] = mempty
idGen f (x:xs) = f x `mappend` idGen f xs
{-# NOINLINE idGen #-}

Again, I use NOINLINE just in case that would help the rules fire. Here is a
main function where the rules should fire:

main :: IO ()
main =
  do print ((fold id . idGen single) [[()]])
 print (fold id (idGen single [[()]]))

But they don't.

Why don't the rules fire, what can I change such that they do, and what to
get rid of the warning for the second rule (which I think is the one I
should use)?

Best regards,
Sebastian

Here is the output of -ddump-simple-stats (once with -fenable-rewrite-rules
only and once with -O):

# ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.1

# ghc -fenable-rewrite-rules -fforce-recomp -ddump-simpl-stats --make rules
[1 of 1] Compiling Main ( rules.hs, rules.o )

 Grand total simplifier statistics 
Total ticks: 0

1 SimplifierDone
1

# ghc -O -fforce-recomp -ddump-simpl-stats --make rules
[1 of 1] Compiling Main ( rules.hs, rules.o )

 FloatOut stats: 
0 Lets floated to top level; 0 Lets floated elsewhere; from 4 Lambda groups



 FloatOut stats: 
10 Lets floated to top level; 1 Lets floated elsewhere; from 5 Lambda groups



 Grand total simplifier statistics 
Total ticks: 144

34 PreInlineUnconditionally
1 eta_Xp5
1 g_amr
1 eta_amx
1 k_amJ
1 z_amK
1 f_amQ
1 g_amR
1 x_amS
1 k_an9
1 z_ana
1 g_anb
1 f_anf
1 xs_ang
1 eta_aoA
2 $dShow_aKW
2 x_aKX
1 ys_aVd
1 c_dmm
1 n_dmn
1 a_snX
1 a_so1
1 lvl_sod
1 lvl_soe
1 lvl_sof
1 lvl_sog
1 lvl_soh
1 lvl_soi
1 lvl_soj
1 a_son
1 a_sop
1 a_sV0
1 a_sV2
17 PostInlineUnconditionally
1 k_amv
1 f_amQ
1 g_amR
1 c_ani
1 n_anj
1 m_anI
1 k_anJ
2 $dShow_aoy
2 x_aoz
1 c_aVa
1 f_aVb
1 x_aVc
1 a_snV
1 a_snZ
1 lvl_sVA
15 UnfoldingDone
1 GHC.Base.build
1 GHC.Base.foldr
2 System.IO.print
1 GHC.TopHandler.runMainIO
2 GHC.Base..
1 GHC.Base.mapFB
1 GHC.Base.$fMonadIO_$c
2 Main.main
2 System.IO.print1
2 GHC.Show.$fShow[]_$cshow
8 RuleFired
1 Class op 
2 Class op show
2 Class op showList
1 fold/build
1 foldr/nil
1 map
8 LetFloatFromLet
8
62 BetaReduction
1 eta_Xp5
1 a_amq
1 g_amr
1 a_amt
1 b_amu
1 k_amv
1 z_amw
1 eta_amx
1 b_amH
1 a_amI
1 k_amJ
1 z_amK
2 b_amN
2 c_amO
2 a_amP
2 f_amQ
2 g_amR
1 x_amS
1 a_an7
1 b_an8
1 k_an9
1 z_ana
1 g_anb
1 a_and
1 a1_ane
1 f_anf
1 xs_ang
1 b_anh
1 c_ani
1 n_anj
1 a_anG
1 b_anH
1 m_anI
1 k_anJ
2 a_aox
2 $dShow_aoy
2 x_aoz
1 eta_aoA
2 a_aKV
2 $dShow_aKW
2 x_aKX
1 elt_aV7
1 lst_aV8
1 a_aV9
1 c_aVa
1 f_aVb
1 x_aVc
1 ys_aVd
1 a_dml
1 c_dmm
1 n_dmn
13 SimplifierDone
13

Re: my RULES don't fire

2011-02-09 Thread Daniel Fischer
On Wednesday 09 February 2011 16:23:15, Sebastian Fischer wrote:
 Why don't the rules fire, what can I change such that they do, and what
 to get rid of the warning for the second rule (which I think is the one
 I should use)?

Didn't spot that, sorry.


 Best regards,
 Sebastian

 Here is the output of -ddump-simple-stats (once with
 -fenable-rewrite-rules only and once with -O):

Users guide says:

(NB: enabling -fenable-rewrite-rules without -O may not do what you expect, 
though, because without -O GHC ignores all optimisation information in 
interface files;



___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


RE: Dictionaries and full laziness transformation

2011-02-09 Thread Simon Peyton-Jones
In general it's quite hard to solve this problem without risking losing sharing.

However in this case I added a simple arity analyser after the 7.0.1 release 
which solves the problem.  It'll be in 7.0.2.

Try with HEAD and check it does what you expect.

Simon

| -Original Message-
| From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-
| users-boun...@haskell.org] On Behalf Of Akio Takano
| Sent: 07 February 2011 04:10
| To: glasgow-haskell-users@haskell.org
| Subject: Dictionaries and full laziness transformation
| 
| Hi,
| 
| I'm using GHC 7.0.1. I found that recursive overloaded functions tend
| to leak memory when compiled with full-laziness optimization on. Here
| is a simple case.
| 
| -- TestSub.hs
| {-# LANGUAGE BangPatterns #-}
| module TestSub where
| 
| {-# NOINLINE factorial #-}
| factorial :: (Num a) = a - a - a
| factorial !n !acc = if n == 0 then acc else factorial (n - 1) (acc * n)
| 
| -- main.hs
| import TestSub
| 
| factorial1 :: Int - Int - Int
| factorial1 = factorial
| 
| main = do
| n - readLn
| print $ factorial1 n 1
| 
| main
| 
| This program should run in constant space, and compiled with -O0 or
| -O2 -fno-full-laziness, it does. However with -O2, it takes a linear
| amount of memory. The core for factorial looks like this:
| 
| TestSub.factorial =
|   \ (@ a_ajm) ($dNum_slz :: GHC.Num.Num a_ajm) -
| let {
|   a_slA :: GHC.Classes.Eq a_ajm
|   [LclId]
|   a_slA = GHC.Num.$p1Num @ a_ajm $dNum_slz } in
| let {
|   lvl2_slC :: a_ajm - a_ajm - a_ajm
|   [LclId]
|   lvl2_slC = TestSub.factorial @ a_ajm $dNum_slz } in
| ...
| 
| The problem is that lvl2_slC closure is created whenever factorial is
| applied to a Num dictionary, and kept alive until that application is
| GCed. In this program it never happens, because an application to the
| Num Int dictionary is referred to by the factorial1 CAF, and it
| recursively keeps the whole chain of closures alive.
| 
| I know that full laziness transformation *sometimes* causes a space
| leak, but this looks like a bad result to me, because:
| 
| - It looks like there is no point building a lot of equivalent
| closures, instead of one.
| - A lot of code can suffer from this behavior, because overloaded
| recursive functions are fairly common.
|   For example, unfoldConvStream function from the latest iteratee
| package suffers from this problem, if I understand correctly.
| 
| Does anyone have an idea on whether this can be fixed in GHC, or how
| to work around this problem?
| 
| Regards,
| 
| Takano Akio
| 
| ___
| Glasgow-haskell-users mailing list
| Glasgow-haskell-users@haskell.org
| http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: my RULES don't fire

2011-02-09 Thread Daniel Fischer
On Wednesday 09 February 2011 16:23:15, Sebastian Fischer wrote:
 Why don't the rules fire,

Because the 'match' is at the wrong type. In main, idGen appears as

idGen_anJ :: ([()] - [[()]]) - [[()]] - [[()]]

at some point (yay for ghc -v4), so it doesn't match g's polymorphic type.

 what can I change such that they do,

Type signatures.

 and what to get rid of the warning for the second rule (which I think
 is the one I should use)?

I'll let that for somebody else.

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: RFC: migrating to git

2011-02-09 Thread Dan Knapp
In my one serious attempt to use git for one of my own projects, some
seemingly-innocuous operation deleted a file on me and I lost a couple
hours of work.  I agree with the people who have said that git's
documentation and semantics are highly confusing, moreso than darcs's.
 For example, what does it mean to stage a commit?  Why is there an
entire GUI window for this presumably-important action, and why do
things I think I've committed not appear in the change history or
mysteriously reverse themselves?

If ghc went to git, it wouldn't make me less likely to contribute, but
I would do so by checking everything into a local darcs repo and using
that to track my own changes, then letting somebody else do the work
of getting them into git!  Which probably would reduce the likelihood
of my patch being accepted, but I consider git a complete waste of my
time and have zero interest in learning to use it.

Plus, while I admire everyone's willingness to consider a VCS that
isn't Haskell-based, I have to admit that there's a Haskell partisan
in me.  And there are real advantages to being a tight-knit community.
 If the GHC maintainers go to the Darcs maintainers and say We
absolutely need feature X or we will have to stop using you, the
Darcs maintainers are likely to say It'll be tough but we'll find a
way to do it.  But we aren't by any means the biggest project using
Git, so the Git maintainers would be likely to say That's nice, keep
in touch.

Obligatory disclaimer - I've never written any code actually in GHC,
although I have used the API (I am the author of direct-plugins).  But
I frequently read its code to clarify how things work, and I do expect
that it's a near-certainty that I'll be hacking GHC itself at some
point in the future.


-- 
Dan Knapp
An infallible method of conciliating a tiger is to allow oneself to
be devoured. (Konrad Adenauer)

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: RFC: migrating to git

2011-02-09 Thread Dan Knapp
I just noticed that the discussion has been concluded and I was replying to an
old thread.  I apologize for the noise.

On Wed, Feb 9, 2011 at 6:56 PM, Dan Knapp dan...@gmail.com wrote:
 In my one serious attempt to use git for one of my own projects, some
 seemingly-innocuous operation deleted a file on me and I lost a couple
 hours of work.  I agree with the people who have said that git's
 documentation and semantics are highly confusing, moreso than darcs's.
  For example, what does it mean to stage a commit?  Why is there an
 entire GUI window for this presumably-important action, and why do
 things I think I've committed not appear in the change history or
 mysteriously reverse themselves?

 If ghc went to git, it wouldn't make me less likely to contribute, but
 I would do so by checking everything into a local darcs repo and using
 that to track my own changes, then letting somebody else do the work
 of getting them into git!  Which probably would reduce the likelihood
 of my patch being accepted, but I consider git a complete waste of my
 time and have zero interest in learning to use it.

 Plus, while I admire everyone's willingness to consider a VCS that
 isn't Haskell-based, I have to admit that there's a Haskell partisan
 in me.  And there are real advantages to being a tight-knit community.
  If the GHC maintainers go to the Darcs maintainers and say We
 absolutely need feature X or we will have to stop using you, the
 Darcs maintainers are likely to say It'll be tough but we'll find a
 way to do it.  But we aren't by any means the biggest project using
 Git, so the Git maintainers would be likely to say That's nice, keep
 in touch.

 Obligatory disclaimer - I've never written any code actually in GHC,
 although I have used the API (I am the author of direct-plugins).  But
 I frequently read its code to clarify how things work, and I do expect
 that it's a near-certainty that I'll be hacking GHC itself at some
 point in the future.


 --
 Dan Knapp
 An infallible method of conciliating a tiger is to allow oneself to
 be devoured. (Konrad Adenauer)




-- 
Dan Knapp
An infallible method of conciliating a tiger is to allow oneself to
be devoured. (Konrad Adenauer)

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: my RULES don't fire

2011-02-09 Thread Sebastian Fischer

  Why don't the rules fire,

 Because the 'match' is at the wrong type.


This was the correct hint, thanks!


  what can I change such that they do,

 Type signatures.


Initially, I thought that just leaving out the polymorphic signature should
fix the problem. But I think it cannot be fixed by changing type signatures
only because once the type of `g` in the rule is fixed, the rule is no
longer type correct!

To overcome this, I have defined

gen :: (forall m . Monoid m = (a - m) - b - m) - b - [a]
gen g = g single
{-# NOINLINE gen #-}

and changed the rules to

{-# RULES
  monoid fusion pointfree
forall f (g :: forall m . Monoid m = (a - m) - b - m) .
  fold f . gen g = g f;

  monoid fusion pointed
forall f (g :: forall m . Monoid m = (a - m) - b - m) b .
  fold f (gen g b) = g f b;
  #-}

and now they fire. Seems a bit roundabout but I don't see how to avoid this
indirection.


  and what to get rid of the warning for the second rule (which I think
  is the one I should use)?

 I'll let that for somebody else.


My new rules don't cause this warning. I'm still interested in what the
warning meant, although my code does not depend on an answer anymore.

Probably because, GHC inlines function composition in the first line of

main = do print ((fold id . gen idGen) [[()]])
  print (fold id (gen idGen [[()]]))

the pointed rule fires twice if I remove the point-free one.

Does it make sense to keep the point-free rule just in case that `fold f .
gen g` is passed to a higher-order function and does not get an argument
after inlining?

Sebastian
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Deriviable type classes

2011-02-09 Thread Yitzchak Gale
Simon Peyton-Jones wrote:
 Generic Defaults... will replace... the Derivable type classes
 stuff... in GHC 7.2 or 7.4...
 Please yell if you are a secret user of derivable type classes,
 so this change would discombobulate you.

Could you give us a preview of the parts of the syntax
spectrum that will be gobbled up by this? That is a way
that the change could affect even people who are not using
the current generics.

For example, the old generics knocked a very nice bracket
out of consideration for TH syntax. It also blessed the names
of certain magical constructors, which can be good to know
about even if the magic doesn't leak out of the generics world.

Thanks,
Yitz

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Dictionaries and full laziness transformation

2011-02-09 Thread Maciej Wos
I've been using ghc-7.1.20110125 and it does indeed help a great deal.
I've tried compiling several problematic functions and in most cases
the problem is gone. However, in one of my test cases the closures are
still being constructed:

let {
  lvl8_s1S8
:: [Data.Iteratee.Base.Iteratee s_aXZ m_aXY a_aY1]
   - Data.Iteratee.Base.Iteratee s_aXZ m_aXY ()
  [LclId, Str=DmdType]
  lvl8_s1S8 =
EnumSequenceTest.enumSequence_
  @ m_aXY
  @ s_aXZ
  @ el_aY0
  @ a_aY1
  $dMonad_s1Q4
  $dListLike_s1Q0
  $dNullable_s1PV } in

The code for enumSequence_ is included in the attachment. There are
two versions:
* enumSequence-bad.hs is the original code
* enumSequence-good.hs includes a fix suggested by Akio

When compiled with ghc-7.1.20110125 and -O2 [1] it uses a lot of memory:

./enumSequence-main +RTS -s
1
1
0
  22,787,568,816 bytes allocated in the heap
   1,455,499,400 bytes copied during GC
 260,651,512 bytes maximum residency (10 sample(s))
  14,457,544 bytes maximum slop
 530 MB total memory in use (0 MB lost due to fragmentation)

  Generation 0: 43936 collections, 0 parallel,  1.58s,  1.57s elapsed
  Generation 1:10 collections, 0 parallel,  1.05s,  1.05s elapsed

  INIT  time0.00s  (  0.00s elapsed)
  MUT   time4.64s  (  4.66s elapsed)
  GCtime2.63s  (  2.62s elapsed)
  EXIT  time0.00s  (  0.00s elapsed)
  Total time7.27s  (  7.28s elapsed)

  %GC time  36.1%  (36.0% elapsed)

  Alloc rate4,905,159,063 bytes per MUT second

  Productivity  63.8% of total user, 63.8% of total elapsed

while compiling with -O2 and -fno-full-laziness or -O0 reverts memory
usage back to constant:

./enumSequence-main +RTS -s
1
1
0
  22,493,819,416 bytes allocated in the heap
 578,891,112 bytes copied during GC
  46,696 bytes maximum residency (1 sample(s))
  19,928 bytes maximum slop
   1 MB total memory in use (0 MB lost due to fragmentation)

  Generation 0: 43335 collections, 0 parallel,  1.07s,  1.07s elapsed
  Generation 1: 1 collections, 0 parallel,  0.00s,  0.00s elapsed

  INIT  time0.00s  (  0.00s elapsed)
  MUT   time4.53s  (  4.55s elapsed)
  GCtime1.07s  (  1.07s elapsed)
  EXIT  time0.00s  (  0.00s elapsed)
  Total time5.60s  (  5.62s elapsed)

  %GC time  19.2%  (19.0% elapsed)

  Alloc rate4,966,355,161 bytes per MUT second

  Productivity  80.8% of total user, 80.5% of total elapsed

-- Maciej

[1] ghc --make -rtsopts -fforce-recomp -O2 enumSequence-bad.hs
enumSequence-main.hs
[2] ghc --make -rtsopts -fforce-recomp -O2 -fno-full-laziness
enumSequence-bad.hs enumSequence-main.hs

On Thu, Feb 10, 2011 at 2:00 AM, Simon Peyton-Jones
simo...@microsoft.com wrote:
 In general it's quite hard to solve this problem without risking losing 
 sharing.

 However in this case I added a simple arity analyser after the 7.0.1 release 
 which solves the problem.  It'll be in 7.0.2.

 Try with HEAD and check it does what you expect.

 Simon

 | -Original Message-
 | From: glasgow-haskell-users-boun...@haskell.org [mailto:glasgow-haskell-
 | users-boun...@haskell.org] On Behalf Of Akio Takano
 | Sent: 07 February 2011 04:10
 | To: glasgow-haskell-users@haskell.org
 | Subject: Dictionaries and full laziness transformation
 |
 | Hi,
 |
 | I'm using GHC 7.0.1. I found that recursive overloaded functions tend
 | to leak memory when compiled with full-laziness optimization on. Here
 | is a simple case.
 |
 | -- TestSub.hs
 | {-# LANGUAGE BangPatterns #-}
 | module TestSub where
 |
 | {-# NOINLINE factorial #-}
 | factorial :: (Num a) = a - a - a
 | factorial !n !acc = if n == 0 then acc else factorial (n - 1) (acc * n)
 |
 | -- main.hs
 | import TestSub
 |
 | factorial1 :: Int - Int - Int
 | factorial1 = factorial
 |
 | main = do
 |     n - readLn
 |     print $ factorial1 n 1
 |
 |     main
 |
 | This program should run in constant space, and compiled with -O0 or
 | -O2 -fno-full-laziness, it does. However with -O2, it takes a linear
 | amount of memory. The core for factorial looks like this:
 |
 | TestSub.factorial =
 |   \ (@ a_ajm) ($dNum_slz :: GHC.Num.Num a_ajm) -
 |     let {
 |       a_slA :: GHC.Classes.Eq a_ajm
 |       [LclId]
 |       a_slA = GHC.Num.$p1Num @ a_ajm $dNum_slz } in
 |     let {
 |       lvl2_slC :: a_ajm - a_ajm - a_ajm
 |       [LclId]
 |       lvl2_slC = TestSub.factorial @ a_ajm $dNum_slz } in
 | ...
 |
 | The problem is that lvl2_slC closure is created whenever factorial is
 | applied to a Num dictionary, and kept alive until that application is
 | GCed. In this program it never happens, because an application to the
 | Num Int dictionary is referred to by the factorial1 CAF, and it
 | recursively keeps the whole chain of closures alive.
 |
 | I know that full laziness transformation *sometimes* causes a space
 | leak, but this looks like a bad result