Loops are another control flow construct which allow us to run some parts of code multiple times. This can either be a known number of times (for-loops) or for as long as some condition is satisfied (while-loops).
Syntax of a for-loop is:
for <loopVariable> in <iterable>:
<loop body>
Traditionally, i
is often used as a loopVariable
name, but any other name can be used.
That variable will be available only inside the loop.
Once the loop has finished, the value of the variable is discarded.
The iterable
is any object we can iterate through.
Of the types already mentioned, strings are iterable objects. (More iterable types will be introduced in the next section.)
All lines in the loop body
are executed at every loop, which allows us to efficiently write repeating parts of code.
If we want to iterate through a range of (integer) numbers in Nim, the syntax for the iterable
is start .. finish
where start
and finish
are numbers.
This will iterate through all the numbers between start
and finish
, including both start
and finish
.
For the default range iterable, start
needs to be smaller than finish
.
If we want to iterate until a number (not including it), we can use ..<
:
link:{source-dir}/for1.nim[role=include]
-
Iterating through a range of numbers using
..
— both ends are included in the range. -
Iterating through the same range using
..<
— it iterates until the higher end, not including it.
5
6
7
8
9
5
6
7
8
If we want to iterate through a range of numbers with a step size different than one, countup
is used. With countup
we define the starting value, the stopping value (included in the range), and the step size.
link:{source-dir}/for2.nim[role=include]
-
Counting up from zero to 16, with a step size of 4. The end (16) is included in the range.
0
4
8
12
16
To iterate through a range of numbers where the start
is larger than finish
, a similar function called countdown
is used.
Even if we’re counting down, the step size must be positive.
link:{source-dir}/for2.nim[role=include]
-
To iterate from a higher to a lower number, we must use
countdown
(The..
operator can only be used when the starting value is smaller than the end value). -
Even when counting down, the step size must be a positive number.
4
3
2
1
0
-3
-5
-7
-9
Since string is an iterable, we can use a for-loop to iterate through each character of the string (this kind of iteration is sometimes called a for-each loop).
link:{source-dir}/for3.nim[role=include]
a
l
p
h
a
b
e
t
If we also need to have an iteration counter (starting from zero), we can achieve that by using for <counterVariable>, <loopVariable> in <iterator>:
syntax.
This is very practical if you want to iterate through one iterable, and simultaneously access another iterable at the same offset.
link:{source-dir}/for3.nim[role=include]
letter 0 is: a
letter 1 is: l
letter 2 is: p
letter 3 is: h
letter 4 is: a
letter 5 is: b
letter 6 is: e
letter 7 is: t
While loops are similar to if statements, but they keep executing their block of code as long as the condition remains true. They are used when we don’t know in advance how many times the loop will run.
We must make sure the loop will terminate at some point and not become an infinite loop.
link:{source-dir}/while.nim[role=include]
-
This condition will be checked every time before entering the new loop and executing the code inside of it.
-
inc
is used to incrementa
by one. It is the same as writinga = a + 1
ora += 1
.
a is: 1
a is: 2
a is: 3
final value of a: 4
The break
statement is used to prematurely exit from a loop, usually if some condition is met.
In the next example, if there were no if statement with break
in it, the loop would continue to run and print until i
becomes 1000.
With the break
statement, when i
becomes 3, we immediately exit the loop (before printing the value of i
).
link:{source-dir}/break.nim[role=include]
1
2
The continue
statement starts the next iteration of a loop immediately, without executing the remaining lines of the current iteration.
Notice how 3 and 6 are missing from the output of the following code:
link:{source-dir}/continue.nim[role=include]
1
2
4
5
7
8
-
Collatz conjecture is a popular mathematical problem with simple rules. First pick a number. If it is odd, multiply it by three and add one; if it is even, divide it by two. Repeat this procedure until you arrive at one. E.g. 5 → odd → 3*5 + 1 = 16 → even → 16 / 2 = 8 → even → 4 → 2 → 1 → end!
Pick an integer (as a mutable variable) and create a loop which will print every step of the Collatz conjecture. (Hint: usediv
for division) -
Create an immutable variable containing your full name. Write a for-loop which will iterate through that string and print only the vowels (a, e, i, o, u). (Hint: use
case
statement with multiple values per branch) -
Fizz buzz is a kids game sometimes used to test basic programming knowledge. We count numbers from one upwards. If a number is divisible by 3 replace it with fizz, if it is divisible by 5 replace it with buzz, and if a number is divisible by 15 (both 3 and 5) replace it with fizzbuzz. First few rounds would look like this: 1, 2, fizz, 4, buzz, fizz, 7, …
Create a program which will print first 30 rounds of Fizz buzz. (Hint: beware of the order of divisibility tests) -
In the previous exercises you have converted inches to centimeters, and vice versa. Create a conversion table with multiple values. For example, the table might look like this:
in | cm ---------------- 1 | 2.54 4 | 10.16 7 | 17.78 10 | 25.4 13 | 33.02 16 | 40.64 19 | 48.26