Loops. The feature that made Cairopractors jealous of every other programming language including Brainfuck. Fortunatelly Cairo 1 fixes that. We have been promised proper for-in loops, but that’s not shipped yet. For now, we have the loop
loop.
We use loops when iterating over arrays. However to do so properly, we need to adhere to certain rules. Shout out to Shahar for highlighting these.
Let’s see how to do it on the Hello world of array looping:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn arr_sum(mut vals: Span<u32>) -> u32 {
let mut sum = 0_u32;
loop {
match vals.pop_front() {
Option::Some(v) => {
sum += *v;
},
Option::None(_) => {
break sum;
}
};
}
}
Breaking it down:
- we pass in a Span because we don’t need to modify the array itself. We also mark the variable as
mut
(necessary forpop_front
) - on line 5, we use
match
to properly deal with theOption<@T>
returned bypop_front
. BTW if you want to iterate in reverse, you can usepop_back
- when summing on line 7, we have to desnap the value of
v
since it’s a snapshot - the Option::None(_) block (line 9) triggers when there’s no more values in the Span, i.e. the looping is done, in which case we
break
with the resultsum
- since we don’t have a
;
on line 13, the return value of the wholeloop
is the return value of the function
Notice there’s no need for a index counter variable from 0 to span.len()
. Neither do we need to get the value at the current index (let v = vals[index]
) which saves us the use of a RangeCheck built-in on every loop iteration.
Happy looping 🔁