[Haskell-cafe] Re: Some random newbie questions

karczma at info.unicaen.fr karczma at info.unicaen.fr
Thu Jan 6 17:55:26 EST 2005


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 




More information about the Haskell-Cafe mailing list