9. Control flow

Like most other programming languages, Mojo provides control structures such as conditions and loops.

9.1. if-else

The most basic control flow is if statement. It takes an expression that must evaluate to a boolean result. The body of the if will be executed if the boolean result is True. It is not allowed to have else without a corresponding if.

    if x == 0:
        print("X is zero")

In this example, we have an if statement with a condition. The == operator checks for equality, here it checks if the variable x has the value 0.

If you want to execute another body of code when the if expression results in False, you can use else.

    if x == 0:
        print("X is zero")
    else:
        print("X is non-zero")

9.2. elif

What if you need to check multiple conditions instead of just one? Mojo provides if-elif-else construct for those cases.

    if x == 0:
        print("X is zero")
    elif x < 0:
        print("X is negative")
    else:
        print("X is positive")

The first if works same as before. The elif is a short form of "else if". It works similar to if and expects the expression to evaluate to True to execute its own body. One thing to note is that if and elif are mutually exclusive and the first one in the sequence of the statements to have expression value as True will execute its body. Therefore care must be taken to correctly order the conditions so that you don’t miss out some edge cases. It is not allowed to have elif without a corresponding if.

    if x == 0:
        print("X is zero")
    elif x == 0:
        print("X is zero - but this won't show up")
    elif x < 0:
        print("X is negative")
    else:
        print("X is positive")

In the previous code listing, since the if condition already evaluated to True, the second elif will not get executed even if the expression is True.

9.3. Nesting of if

You can nest if inside another if or else or elif. This allows for implementation of a more complex control flow logic.

    if x < 0:
        print("X is negative")
        if x < -5:
            print("X is too low")
    else:
        if x == 0:
            print("X is zero")
        print("X is positive")

Too many nested conditions could impact readability of the code. In this case consider whether extracting them into separate functions improve readability.

9.4. if as expression

The standard if statement spans over a minimum of 4 lines, sometimes when we just want to assign a value conditionally to a variable, it is a bit verbose. Mojo provides a shorter one line version that could be used in such cases.

    var message = "X is positive" if x >=0 else "X is negative"
    print(message)

One thing to note here is that the order of the if expression is different from the usual order of if statements.

The anatomy of if-elif-else is shown in the following diagram.

If

9.5. case

9.6. while

The while loops allow a body of code to be executed repeatedly as long as the condition of the while evaluates to True. The moment the condition evaluates to False, it stops executing the code body within it.

    x = 0
    while x <= 5:
        print("X is: ", x)
        x = x + 1

The previous code listing will print values 0 to 5.

It is possible to add else clause after the while body. The else body will be executed exactly once when the condition of while evaluates to False.

    x = 0
    while x <= 5:
        print("X is: ", x)
        x = x + 1
    else:
        print("X is now greater than 5")

The previous code listing will print "X is now greater than 5" after printing values 0 to 5.

The anatomy of a while loop is shown in the following diagram.

While

9.7. for

Similar to while, for also provides facility to repeat a code block many times. The main difference is that while is based on an expression evaluating to True whereas for is based on something called an iterator.

In the most simple term, an iterator is something that returns an element when its next method is called. The expression that comes after in within the for loop statement must resolve to an iterable. An iterable is anything that returns an iterator when its iter method is called. In effect, when the for loop is executed, it calls the iterable’s iter method which returns the iterator the for loop works with. For each repetition of the loop, the iterator’s next is called and its result assigned to the variable coming before the in keyword. The iterator must keep track of the state so that the for loop advances to the next element when next is called.

    for i in range(0, 5):
        print(i)

It is possible to add else clause after the for body. The else body will be executed exactly once when the iteration is finished.

    for i in range(0, 5):
        print(i)
    else:
        print("i is now greater than 4")

The anatomy of a for loop is shown in the following diagram.

For

9.8. Skipping and exiting early from loops

9.8.1. break

If you want to exit the while or for loop early (usually on some condition), then you can use break. This allows early exit from the loop.

    x = 0
    while x <= 5:
        if x > 3:
            break
        print("X is: ", x)
        x = x + 1
    
    for i in range(0, 6):
        if i > 3:
            break
        print("i is: ", i)

The previous code listing will print values 0 to 3, and will exit the loop as soon as x is greater than 3.

9.8.2. continue

What if you wanted to skip an iteration of the loop? For this case Mojo provides you with continue. The continue keyword would skip all the statements coming after it in the while or for body for exactly one iteration of the loop.

    x = 0
    while x <= 5:
        x = x + 1
        if x < 3:
            continue # Skip following statements of the while block
        print("X is: ", x)

    for i in range(0, 6):
        if i < 3:
            continue # Skip following statements of the while block
        print("i is: ", i)

The previous code listing will skip the print statement coming after it until value of x is greater than or equal to 3.