[Haskell-cafe] Re: [Haskell] lazy constructors

Serge D. Mechveliani mechvel at botik.ru
Thu Oct 14 00:57:17 EDT 2004


I thank  Jeremy Gibbons, Ben Rudiak-Gould, and other people,
for their helpful explanations.


On Wed, Oct 13, 2004 at 02:34:55PM +0100, Ben Rudiak-Gould wrote:
> Serge D. Mechveliani wrote:
> 
> >  As the types are resolved before the computation, as the above
> >  program shows, how can addToSPair expect anything besides a string
> >  pair? Why tilda is not a default?
> 
> Haskell pairs are "lifted", meaning that they also include an extra 
> value (bottom) which doesn't match (x,y). Not everyone is convinced that 
> this is a good idea, but it's the way things are at present.
> 
> >  The only doubt may be the matching of (xs, ys) against
> >  bottom :: (String, String) Is not this natural to have a result as
> >  (bottom :: String, bottom :: String) -- = xs = ys and
> >  compute further?
> 
> Possibly in this case, yes. But not in general, since there might be 
> other data constructors also.
> 
> >  What will occur if all the Haskell programmers set `~' before each
> >  data constructor in each pattern in their existing programs?
> 
> Things won't work as you'd expect. For example, if you defined
> 
>     null :: [a] -> Bool
>     null list =
>       case list of
>         ~(x:xs) -> False
>         ~[]     -> True
> 

I am sorry. Of course, I meant the functions in which it was set 
initially only a single pattern. People often write such.

> >  As the types are recognized before the computation, the programs will
> >  remain safe and will become considerably faster. For example, the
> >  above program of g1 becomes a billion times faster. I wonder.
> 
> Actually using irrefutable patterns tends to make a program slower, not 
> faster, because it makes the program less strict.
> 


Probably, unneeded strictness bites more seriousely than unneeded 
laziness.
What I fear of is the following hidden slow down.

Suppose that such a function (as the above  addToPair) updates a value
of type  ([a], [b])  in a loop.  And consider a client function

   let  p = form_list_pair_via_addToPair ...
        ...
        h = g p p
        ... 
   in
   if  (take 3 $ fst p) == "abc"  then ... else ...

The value of  p  is used in several places, the whole program looks
natural.
The programmer relies on that  (take 3 $ fst p)
computes `lazily'.
In fact, I like to rely on the `laziness' and think that it makes the 
programs more clear. Otherwise, one could program, say, in ML.

Now, if one does not guess to set tilda in  addToPair,  
the whole program becomes slower somewhat in 
                                             (length xs)/3  times!

Here  xs  is a list accumulated in the first component of the 
form_list_pair_via_addToPair  result.
If  length xs = 900,  then the slow down in 300 times.

Is there any systematic approach allowing to avoid a performance 
adventure like this?
May the compiler help, may it issue a warning?
And maybe, there are other sources of the slow downs due to unneeded
strictness.

Regards,

-----------------
Serge Mechveliani
mechvel at botik.ru





More information about the Haskell-Cafe mailing list