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

Jerzy Karczmarczuk karczma@info.unicaen.fr
Tue, 02 Dec 2003 12:07:25 +0100


John van Groningen wrote:

> The compiler generates incorrect code for a strict or unboxed
> list constructor on a cycle that is in a strict context or
> in a lazy context with an already evaluated head (or tail for
> tail strict lists).
...
 > An improved backend.dll for windows is available [...]


Thank you very much John for so prompt reaction. I knew I can
count on you, but less than 24 hours to correct a compiler bug?

And thank you for your comments concerning the efficiency of
all these (=:) and (:==) intricacies.

Clean is full of black magic. Perhaps one day some specific
categories of advice, notably about the Essence of Laziness/
Strictness might be better documented?

I have one case which I don't *really* understand, although
I understand it superficially, and there is nothing wrong with
it. My bombed examples -- the sampled sinusoid and the other
lazy stream, which implements co-recursively the Karplus-Strong
algorithm -- are *sound* samples. Converted to *{#Char} and
played as .wav buffers.

You may imagine that in the case of sound the synchro- asynchro-
issues are quite important. But sometimes the graph-reduction
has its own ideas about the order of events. Look at the
[fragment of the] following program:

// ========================
Start :: *World -> (*World,*File)
Start wrld
   # (console,wrld) = stdio wrld
   # console = fwrites "beginning of first fragment\n" console
   # (a,wrld)  = playWav "file1.wav" wrld
   # console = fwrites "end of first fragment\n" console
   # (b,wrld) = playWav "file2.wav" wrld
   # console = fwrites "end of second fragment\n" console
   = (wrld,console)
// ========================

Its execution begins by writing:

(



Then *both* files are played,
and finally the console displays at once:

  65536,beginning of the first fragment
end of first fragment
end of second fragment
(File -1 4254404)

//////////////////////////////////////////////////////////////////////

Hmmm. I thought then that forcing the strictness of the sharp-let will
serialize the actions appropriately. It does serialize them, but in
a way I *didn't*  expect.

Replace all # by #!

The result is: first, the console writes the text:

beginning of the first fragment
end of first fragment
end of second fragment

... and then plays both files. And finishes by writing (65536,File -1 4250308)

I imagine that demanding the interaction and forcing the reading of something
will - perhaps - change this order, but without that, what would be your
recommended way to serialize (monadify??) the actions above in an intuitive
(obvious) order?

***

My superficial understanding is that the lines which use console are chained
independently of instructions which handle wrld, so there is - a priori - no
intrinsic, explicitly visible relative order among them.
So I replaced everywhere

console = XXX console

by

(console,wrld) = (XXX console,wrld)

but it didn't help. Perhaps it has been simply optimized away. Perhaps the idea
is too silly [which I suspect].


Thank you. And I promise more...

Jerzy Karczmarczuk