[clean-list] Strict lists kill me...

Jerzy Karczmarczuk karczma@info.unicaen.fr
Mon, 01 Dec 2003 09:48:52 +0100


Gentle gurus.
I wrote a short program which generates co-recursively a stream
representing the sampled sine function, using the identity:

sin(x+2h) = 2 sin(x+h)*cos(h) - sin(x)

Of course, the algorithm shown below being co-recursive needs spine
laziness. But I don't need - I think... - to have the head laziness.
So, I wrote three identical versions using [], [!] and [#]. Here it is:

// =============================================
module litest
import StdEnv, StdStrictLists, StdOverloadedList

class (*>)  infixr 7 t   :: !Real (t Real) -> (t Real)
instance *> [] where
  (*>) x l = map (\s -> x*s) l
instance *> [!] where
  (*>) x l = Map (\s -> x*s) l
instance *> [#] where
  (*>) x l = Map (\s -> x*s) l

ZipWith op [|a:as] [|b:bs] = [|(op a b) : ZipWith op as bs]
ZipWith op as bs		   = [|]

instance - [#Real]
where
  (-) l1 l2 = ZipWith (-) l1 l2
instance - [!Real]
where
  (-) l1 l2 = ZipWith (-) l1 l2
instance - [Real]
where
  (-) l1 l2 = ZipWith (-) l1 l2

oscilu =: (z,v,r) where
  z =: [# 0.0 : v]
  v =: [# sin 0.01 : r]
  r =: (2.0*cos 0.01)*>v - z

oscils =: (z,v,r) where
  z =: [! 0.0 : v]
  v =: [! sin 0.01 : r]
  r =: (2.0*cos 0.01)*>v - z

oscill =: (z,v,r) where
  z =: [0.0 : v]
  v =: [sin 0.01 : r]
  r =: (2.0*cos 0.01)*>v - z

Start = let (a,b,c) = oscill
  in (Take 10 a, Take 10 b, Take 10 c)
// ====================================================

The operator (*>) multiplies a list by a scalar. It, and the 2-mapped (-)
are duly overloaded. The result is the list, its tail, and its tail_tail.
Yes, it seems silly, first element should suffice. But now comes the issue.

The program - as it is - produces the expected result.

Change oscill into oscils in Start. Ready to guess the result?
Here it is:

([],[.0099998333416666],[])

Nice, isn't it, especially the tail of the empty list...

============================================================================

Now, change oscils into oscilu.  Ready for another guess?



(Run Time Warning:  cycle in spine detected


***************************************************************************

This is all. I suspect that this might be a bug somewhere in the treatment
of not-entirely-lazy lists. Perhaps the translation between (:) and cons,
cons_u or whatever is imperfect. Perhaps the overloading plays some dirty
tricks.
Or, perhaps I simply I did something illegal in my coding, in this case
I would very humbly suggest to introduce some appropriate caveats into the
documentation...


Thank you.


Jerzy Karczmarczuk
Caen, France