Array repeat
Listing every element works for four values, not for sixteen — and not at all for a thousand. [value; count] builds an array of count copies of one value: [0; 16] is sixteen zeros. This lesson shows the form, its one surprise, and the job it is usually given: starting an array from a clean slate.
Many copies of one value
let zeros: int32[16] = [0; 16];
Read [0; 16] as "zero, sixteen times". The element type comes from the variable — here int32, because the variable says int32[16] — and the count must match the count in the type.
The count must be known at compile time, because it becomes part of the array's type. A literal works, and so does a const, but a let variable does not: its value is only known once the program runs.
The value is evaluated once
The surprise is in how the value is produced. It is evaluated exactly once, and that one result is copied into every element:
let rolls = [Roll(); 4];
Roll prints a line every time it is called, and the output shows Roll called only once. The four elements are always equal, whatever Roll returns.
flowchart LR
r["Roll()<br/>called once"] --> v["4"]
v --> e0["rolls[0] = 4"]
v --> e1["rolls[1] = 4"]
v --> e2["rolls[2] = 4"]
v --> e3["rolls[3] = 4"]If you want each element computed on its own, list them — [Roll(), Roll(), Roll(), Roll()] makes four calls — or fill the array in a loop.
A clean slate to fill in
The usual reason to repeat a value is to start a var array from zero and fill it in afterwards. Here, a tally of the last digit of each number:
var tally: int32[10] = [0; 10];
let numbers: int32[8] = [12, 7, 22, 35, 2, 17, 40, 32];
for number in numbers {
tally[number % 10] += 1;
}
number % 10 is the last digit, 0 to 9, so it is always a valid index into tally. Each element counts how many numbers end in that digit: 12, 22, 2 and 32 all land in tally[2].
The program
The whole lesson is one package in the Examples repository. Its comments explain every step.
// Listing every element works for four values, not for sixteen. `[value; count]` builds an array
// of `count` copies of one value: `[0; 16]` is sixteen zeros, of type `int32[16]` when the
// variable says so.
//
// The surprise is in how the value is produced. It is evaluated exactly once, and that one
// result is copied into every element. `[Roll(); 4]` calls `Roll` once, not four times, so the
// four elements are always equal.
import Io::PrintLine;
// Prints a line every time it is called, so the output shows how many calls happened.
func Roll() -> int32 {
PrintLine("Roll called");
return 4;
}
func Main() -> int {
// The count must be known at compile time; the element type comes from the variable.
let zeros: int32[16] = [0; 16];
PrintLine("zeros: length {}, first {}, last {}", zeros.length, zeros[0], zeros[15]);
// One call, four copies of its result.
let rolls = [Roll(); 4];
PrintLine("rolls: {} {} {} {}", rolls[0], rolls[1], rolls[2], rolls[3]);
// The usual reason to repeat a value is to start a `var` array from a clean slate and
// fill it in afterwards. Here, a tally of the last digit of each number.
var tally: int32[10] = [0; 10];
let numbers: int32[8] = [12, 7, 22, 35, 2, 17, 40, 32];
for number in numbers {
tally[number % 10] += 1;
}
for digit in 0..tally.length {
if tally[digit] > 0 {
PrintLine("ending in {}: {}", digit, tally[digit]);
}
}
return 0;
}
Run it
cd Examples/Sequences/ArrayRepeat
rux run
zeros: length 16, first 0, last 0
Roll called
rolls: 4 4 4 4
ending in 0: 1
ending in 2: 4
ending in 5: 1
ending in 7: 2
Common mistakes
With
let n = 4;, the literal [0; n] fails with error: array repeat count must be a non-negative compile-time integer. Use a literal or a const.let b: int32[5] = [0; 4]; fails with error: cannot assign 'int[4]' to 'int32[5]'. The repeat count and the type's count have to be the same number.[Roll(); 4] calls Roll once. If each element should be different, list the calls or assign the elements in a loop.Try it yourself
- Declare
const Size = 5;and use it in both places:var squares: int32[Size] = [0; Size];. Fill the array with the squares of its indices — they areuint, so convert withas int32. - Replace
[Roll(); 4]with[Roll(), Roll(), Roll(), Roll()]and count theRoll calledlines. - Change the tally to count the remainders of each number divided by 3 instead.
- Try
[0; n]with alet n = 4;and read the error.
Learn more
- Arrays in the Rux Reference
- Const — a value known at compile time
- Array nested — repeating a whole row to build a grid