| I encountered the problem that a partially computed infinite list fills up
| the heap, and that Hugs fails to release it. I use the MacPPC port I made,
| but I gather it does not have anything to do with the port, but with the
| Hugs kernel itself.
|
| The file "fib.hs" contains the following definition of Fibonacci number as
| an infinite list:
| fib     :: [Integer]
| fib     = 1 : 1 : [ a+b | (a,b) <- zip fib (tail fib) ]
|
| ...
|
| It appears that once Hugs has filled up the heap with partial computations
| of the infinite list "fib", it keeps it there, and does not release it no
| matter what.

Your observations are correct, and this was an intentional design feature of
Gofer, which has carried over into Hugs.  There is a simple way to release
the
storage for fib, which is to reload fib.hs (or any other file, or even
nothing
using :load with no arguments).

This has been a controversial point in the design, and some folks will tell
you that I made the wrong choice.  I'm sure that I've written about my
rationale for this behaviour in the Gofer user manual or implementation
report, so I won't go into it again here.  I will however note that, if you
want to write a version of fib that doesn't hold on to the partially
computed list beyond a single use of that list, then you should rewrite your
definition as:

  fib   :: () -> [Integer]
  fib () = fibs where fibs = 1 : 1 : zipWith (+) fibs (tail fibs)

And compare the behavior of this definition with the following, seemingly
modest variation:

  fib   :: () -> [Integer]
  fib () = 1 : 1 : zipWith (+) (fib ()) (tail (fib ()))

The moral of this story is that programmers with only finite amounts of
memory do sometimes have to worry about sharing and about the way that
memory is being used.  And some aspects of memory usage are very subtle.
For example, if you rewrote the above definition as:

  fib  :: () -> [Integer]
  fib u = 1 : 1 : zipWith (+) (fib u) (tail (fib u))

then I think you'd see a different space behavior, courtesy of
something in Hugs called the `root optimization'.  I suspect that some
of these behaviors will be different in the next generation, STG Hugs.
Alas, we don't yet have a specification for Haskell that enables a
programmer to understand and anticipate the space behavior of any given
Haskell program across all implementations.

All the best,
Mark

Reply via email to