Getting started
Appends 1 as an item to the list sequence
2.4 Control flow
There are many ways to control the flow of execution in Nim. The most common is the if statement, which you’ve already seen in action in section 2.1.
The if statement is a conditional statement: when its condition is true, its body is executed. Nim’s if statement is similar to the if statement in other languages. It sup-ports multiple “else if” blocks specified using the elif keyword and an “else” block using the else keyword.
if age > 0 and age <= 10:
echo("You're still a child") elif age > 10 and age < 18:
echo("You're a teenager") else:
echo("You're an adult")
Switch statements are also supported, although in Nim they’re known as case state-ments because they begin with the case keyword. They reduce repetition when you need to handle many different conditions.
case variable
of "Arthur", "Zaphod", "Ford":
echo("Male") of "Marvin":
echo("Robot") of "Trillian":
echo("Female") else:
echo("Unknown")
Where the Nim case statement differs from the ones in other languages is in its lack of fall-through, which is the continuing execution of further case statements until a break keyword is used. Fall-through enables multiple values to match the same code block, but it usually requires a large number of break keywords to be used. Nim still allows multiple values to match the same code block, but it uses a different syntax.
An of branch in a case statement can contain a list of values to be matched, as well as a range, similar to the ranges used in set constructors. For example, matching every number from 0 to 9 can be done like this: of 0 .. 9:.
In Nim, every statement can be an expression. One case where this is useful is when you wish to assign a value depending on a condition:
let ageDesc = if age < 18: "Non-Adult" else: "Adult"
You can use the case statement as an expression in a similar way.
The flow of your program can also be controlled using loops. There are two loop-ing statements in Nim. You’ve already seen examples of the for loop. There’s also a while loop that you can use.
The while loop is the most basic of the looping statements. It consists of a condi-tion that gets evaluated before each loop. If that condicondi-tion is true, the loop continues.
var i = 0 while i < 3:
echo(i) i.inc
This code would output the following:
0 1 2
Just like in other languages, the continue and break keywords allow you to control a loop. The continue keyword will skip the current iteration and restart from the top of the loop body. The break keyword will end the iteration.
Loops while the variable i is less than 3
Declares a new mutable variable and assigns it the value 0
Increments the i variable (adds 1 to its current value) Displays the current
value of the variable i
You can also nest looping statements, and you may wonder how to break out of multiple loops at once. This can be solved by specifying a label for the break keyword.
The label must be defined by the block keyword, and breaking to that label will cause the execution to break out of every loop inside that block.
block label:
var i = 0 while true:
while i < 5:
if i > 3: break label i.inc
Another feature of the block keyword is that it introduces a new scope whenever it’s used.
Nim supports the concept of iterators. These are similar to procedures, but they yield values to their caller multiple times, instead of returning just once. An iterator can be specified in a for statement, and it’s then advanced after each iteration. The value that it yields is available in the body of the for statement.
iterator values(): int = var i = 0
while i < 5:
yield i i.inc
for value in values():
echo(value)
The preceding example produces the following output:
0 1 2 3 4
There are many general iterators that work on sequences and other collection types, and there are also specific iterators like the walkFiles iterator, which, when given a pattern, iterates over the files in the current directory that match that pattern. For example, to find all the files ending with a .nim extension in the current directory, you’d do something like this:
import os
for filename in walkFiles("*.nim"):
echo(filename)
The for loop in Nim is most similar to the one in Python, as shown in figure 2.2.
Loops while variable i is less than 5 This loop will iterate forever.
Once i is greater than 3, jumps
out of the block named label Increments the variable i
Execution will resume here once break label is called.
Imports the os module that defines the walkFiles iterator
Iterates over each filename with the .nim extension Displays the filename during each iteration
In Python, you can iterate over any object that defines the __iter__ method, and this can be done implicitly without needing to call the __iter__ method in the for loop.
Nim supports a similar mechanism:
for item in @[1, 2, 3]:
echo(item)
Nim will implicitly call an iterator by the name of items. Which specific items iterator will be called depends on the type of the value specified after the in keyword; in this case it’s seq[int].
If an items iterator that matches the type can’t be found, the compilation will fail with a type mismatch error, as in this example:
for i in 5:
echo i
Here’s the compilation output:
file.nim(1, 10) Error: type mismatch: got (int literal(5)) but expected one of:
system.items(a: array[IX, T]) system.items(E: typedesc[enum]) system.items(s: Slice[items.T]) system.items(a: seq[T])
system.items(a: openarray[T]) system.items(a: string) system.items(a: set[T]) system.items(a: cstring)
The items iterator is only invoked when you specify one variable in the for loop; a pairs iterator is invoked for two variables. The values that the pairs iterator typically returns are the current iteration index and the current item at that index:
for i, value in @[1, 2, 3]: echo("Value at ", i, ": ", value) for keyword
One or more loop variables
in keyword
Iterator call or variable
Loop body
Figure 2.2 for loop syntax in Nim
The preceding code will produce this output:
Value at 0: 1 Value at 1: 2 Value at 2: 3
There’s no default name for an iterator yielding three values or more.