Why is Flatten implemented the way it is?
Raphael Collet
raph at info.ucl.ac.be
Thu Mar 24 16:30:23 CET 2005
Yves Jaradin wrote:
> Contrary to my expectations, I found List.flatten to be non-incremental
I had a look at the sources. You're right. The Flatten in the sources
is non-incremental and not very readable.
> (no result is available until the whole structure has been processed). I
> supposed that Flatten was implemented as:
>
> local
> fun{Flatten2 Xs End}
> case Xs
> of nil then End
> [] H|T then {Flatten2 H {Flatten2 T End}} % rather than the
> incremental: []H|T then R I in {Flatten2 H I R} {Flatten2 T End I} R
> else Xs|End
> end
> end
> in
> fun{Flatten Xs}
> {Flatten2 Xs nil}
> end
> end
Well, your proposal is not incremental either... Even the following
expression is non-incremental (see why?).
R I in {Flatten2 H I R} {Flatten2 T End I} R
You have to write it as a procedure:
%% incremental flatten with difference lists
local
proc {DoFlatten L Start End}
case L
of nil then Start=End
[] X|T then S in {DoFlatten X Start S} {DoFlatten T S End}
else Start=L|End
end
end
in
fun {Flatten L}
{DoFlatten L $ nil}
end
end
Here is another idea. It is completely tail-recursive, and uses an
explicit stack instead of two recursive calls. This one is well
designed to become lazy.
%% incremental tail-recursive flatten
local
fun {DoFlatten L Stack}
case L
of X|T then {DoFlatten X T|Stack}
[] nil then {DoFlatten Stack nil}
else L|{DoFlatten Stack nil}
end
end
in
fun {Flatten L}
{DoFlatten L nil}
end
end
> The current implementation of Flatten is also different from the rest of
> the List module in it's treatment of '|'-labeled tuples with a non-list
> second member. Those are errors in all the other cases but for Flatten
> they are just non-list values.
Do you mean: {Flatten 1|2} is accepted, and returns 1|2? No a great
feature indeed.
> Has someone ever written code depending on this behavior? (which isn't
> documented, documentation for Flatten isn't precise at all)
> Are those problems worth an incompatible change in future releases?
I think it is worth the change. It will create a natural selection
process on programmer that may rely on the unexpected feature ;-)
Cheers,
raph
More information about the mozart-hackers
mailing list