Dynamic arrays gave you growth; this page gives
you order — and its opposite, on purpose. The arrays unit sorts and
copies pieces; the random unit shuffles and rolls, and its disorder is
the reproducible kind: seeded, defined by pure integer arithmetic, the same
on every machine at every tier.
The example is examples/OrderAndDisorder
in the tutorial repository.
Getting the file
make -C examples/OrderAndDisorder runOrderAndDisorder
sorted 1 3 4 7 8 9
middle three 4 7 8
shuffled(7) 3 9 1 4 8 7 - sum still 32
three dice 4 5 1Run it on another machine, another architecture, another optimization tier: the shuffled line and the dice are the same. That is the page’s headline, and it is not an accident.
The example, walked
Sort: the guarantees a systems library owes
Sort(address ns);Sort is a native generic heapsort over any dynamic array whose elements
are ordered. The comparison is the element type’s own < — the generics
machinery clones the routine per element type and compares in line, so
there is no comparator to hand over and nothing the type checker cannot
see. The properties are the ones worth promising: it sorts in place with
no allocation at all, so it works unchanged where no heap exists; its
worst case equals its best at O(n log n), so no adversarial input degrades
it; and its stack use is a handful of locals however large the array grows.
One property is documented rather than promised: the sort is unstable by design. Over an ordered element domain equal values are indistinguishable, so the difference cannot be observed; stability starts to matter when records sort by one field — a surface that arrives with record ordering, and a limitation the known limitations page states openly.
SubArray: the named piece
SubArray(address ns, 2, 3, address piece);Elements 2, 3 and 4, copied into a list the caller owns — the value rule’s spelling of a slice, consistent with everything the slicing page taught: a piece you name is a copy you own.
Shuffle: disorder you can rerun
rng := Seeded(7);
Shuffle(address ns, address rng);The generator behind Shuffle is seeded and deterministic: its whole
definition is integer arithmetic, so the same seed yields the same
sequence on every architecture at every tier — the determinism the rest of
the language promises, extended to randomness. A repeatable test, a
simulation you can bisect, a training run you can reproduce: all of them
want exactly this. The state is a plain value you own and pass by
address, the same visible-mutation marker as everywhere else — no
ambient generator, no hidden global to make two tests interfere.
RangeInt draws from an inclusive range, Float from [0, 1), Next
answers raw words. And the printed sum beside the shuffled line is the
completeness check in this page’s spirit: rearranged, never lost.
One boundary, stated plainly: this generator is for simulation, testing and games. It is deliberately not cryptographic — key material comes from the platform’s own entropy door, not from here.
Try it
1. Change the seed. Seeded(8) — a different order, equally fixed.
Rerun twice; it does not budge. Then put 7 back and watch the page’s
exact line return.
2. Sort the shuffle. Add a second Sort(address ns); after the
shuffle and print again: 1 3 4 7 8 9. Order and disorder are inverse
verbs over one value, which is the page’s quiet point — neither is special,
both are yours.
Next
Dynamic arrays for the container these verbs serve, and WYSIWYG slicing for pieces of shaped values. Every example lives in the tutorial repository.