[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