
A "random newbie" called (randomly probably) Benjamin Pierce writes:
* I wrote a little program for generating Sierpinkski Carpets, and was astonished to find that it runs out of heap under Hugs (with standard settings -- raising the heap size with -h leads to a happier result).
...
import SOEGraphics
fillSquare w x y s = drawInWindow w ...
carpet w x y s = if s < 8 then fillSquare w x y s else let s' = s `div` 3 in do carpet w x y s' carpet w (x+s') y s' carpet w (x+s'*2) y s' carpet w x (y+s') s' carpet w (x+s'*2) (y+s') s' carpet w x (y+s'*2) s' carpet w (x+s') (y+s'*2) s' carpet w (x+s'*2) (y+s'*2) s'
main = runGraphics ( do w <- openWindow "Carpet" (700,700) carpet w 50 50 600 k <- getKey w closeWindow w )
I've clearly got a lot to learn about space usage in Haskell... can someone give me a hint about what is the problem here and how it might best be corrected?
Interesting (although hardly encouraging...) to see that other people fell victim of *exactly* the same problem as myself, when I tried to switch from Scheme to Haskell/Hugs while teaching graphics... In any case, Maestro, don't try to put your 'carpet' procedure under the microscope, since in fact you have been stabbed in the back with an empoisoned knife. This program, whose complexity can hardly be called exorbitant also slllooooowwwwwwwwsss down, and fails in GC: ========= fillSquare w x y s = drawInWindow w (withColor Blue (polygon [(x,y), (x+s,y), (x+s,y+s), (x,y+s), (x,y)])) loopx w x y s = if x>s then return () else do {fillSquare w x y 5; loopx w (x+5) y s} blob w x y s = if y>s then return () else do{loopx w x y s; blob w x (y+5) s} main = runGraphics ( do w<-openWindow "Blob" (900,900) blob w 50 50 800 k<-getKey w closeWindow w ) =============== Greg Buchholz example with generating PS shows that even a non-optimized program which avoids SOE works... It seems that there is something nasty with SOEGraphics, concretely with window painting procedures (and with other operations "iterated", where the quotes around "iteration" is a sad irony...). It seems that Nothing Is Forgotten, or worse. Well, the following version: ************ loopx :: Window -> Int -> Int -> Int -> IO () loopx w x y s = if x>s then return () else (fillSquare w x y 5) `seq` (loopx w (x+5) y s) blob :: Window -> Int -> Int -> Int -> IO () blob w x y s = if y>s then return () else (loopx w x y s) `seq` (blob w x (y+5) s) ************ works pretty fast (under Windows 2000). But doesn't paint anything. Perhaps I should use some deepSeq, or whatever? Sorry for not having anything more optimistic to say. In fact, waiting for better weather I do such exercises using Clean... Jerzy Karczmarczuk