For and While Loops

Looping structures, i.e. for and while loops, are another method of flow control in Julia programming. They can be used to perform structured and/or repeated tasks that occur numerous times in a compact way.

For loops

For loops are a looping structure that allows for iteration over a fixed number of items. The items can simply be monotonically increasing integers, in which case the loop simply cycles a fixed number of times. Additionally, the items can by items from a Julia Array, Tuple, or Dict or other iterable types

For demonstration purposes, let’s start with a Julia Array of type Any.

alist = [1, 2.0, "hello"]
3-element Vector{Any}:
 1
 2.0
  "hello"

Now we can write a for loop that iterates over each item in the list one at a time and prints the item to the screen.

In this loop item becomes a variable internal to the loop that each entry in alist gets assigned to one-by-one as the program cycles through the body of the loop until the end of alist has been reached.

for item in alist
    println(item)
end
1
2.0
hello

The loop above is exactly equivalent to this code

item = alist[1]
println(item)
item = alist[2]
println(item)
item = alist[3]
println(item)
1
2.0
hello

The code above is said to be the unrolling of the loop. Of course, if alist had many items in it, we would not want to type all the lines of code required to perform the operation without the loop.

Just like Julia functions and if statements, loops use and end keyword to indicate the end of body of the loop. What is in the body gets executed every cycle through the loop, any valid Julia code can be placed in the body.

The StepRange type provides a quick way to generate a monotonically increasing set of integers for iteration.

for i = 0:2:6
    println(i ^ 2)
end
0
4
16
36

Tuples can be iterated over in a for loop just like lists.

atuple = (1, 3, 5)

for item in atuple
    println(item)
end
1
3
5

Dictionaries can also be iterated over, by default iterating over a Dict returns a tuple of (key, value) pairs to be unpacked and assigned each to variables local to the loop.

If only dictionary keywords where desired for iteration in the loop, the keys() function could be used. Likewise values() can be used if only the values are desired. The functions turn the respective keys and/or values into an Array.

adict = Dict("name1" => "Romeo", "name2" => "Juliet")

for (keyword, value) in adict
    println("$(keyword) is $(value)")
end
name2 is Juliet
name1 is Romeo

Often times we would like to store the results of computations in a Array as the loop executes. One way to do this is using the push!() function defined for Arrays. Here we start with an empty Array of type Any and append the square of the integer range of numbers from 0 to 10 each cycle through the loop.

alist = []

for item = 0:10
    push!(alist, item ^ 2)
    println(alist)
end
    
print(alist)
Any[0]
Any[0, 1]
Any[0, 1, 4]
Any[0, 1, 4, 9]
Any[0, 1, 4, 9, 16]
Any[0, 1, 4, 9, 16, 25]
Any[0, 1, 4, 9, 16, 25, 36]
Any[0, 1, 4, 9, 16, 25, 36, 49]
Any[0, 1, 4, 9, 16, 25, 36, 49, 64]
Any[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Any[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Any[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

List comprehensions

There is another type of for loop structure that can be used in Julia when it is desired to store the output of computations from a loop in a Array. These are called comprehensions. An example of a list comprehension that produces the same result as the for loop above is

In a list comprehension, the body of the loop goes before the for keyword.

alist = Any[item ^ 2 for item = 0:10]
print(alist)
Any[0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

Enumerate

Occasionally, in addition to iterating over the actual items in a Array/Tuple, the integer index corresponding to the location in the data structure is also desired. This can be returned with the enumerate() function. For example,

atuple = ("a", "tuple", "of", "strings")

for (count, item) in enumerate(atuple)
    println("$(item) -- has the index $(count)")
end
a -- has the index 1
tuple -- has the index 2
of -- has the index 3
strings -- has the index 4

While loops

While loops continuously execute the body of the loop so long as some conditional statement is evaluating to true. The conditional statement appears to the right of the while keyword. In the example below, we use a very simple conditional statement, but any valid conditional expression in Julia, including && and || operators can be used.

Here the conditional statement is i < 5 which of course is true with the given initial value of i=0. So the body of the loop executes, each time incrementing i by 1, until i = 5 which causes the conditional statement to evaluate to false and the loop exits.

i = 0

while (i < 5)
    
    println(i)
    
    i += 1
end
0
1
2
3
4

If the conditional statement in a while loop never evaluates to false, the loop will execute ad infinitum. If new variables are being assigned in the body of the loop or the results of computations are stored, the infinite cycling can cause the computer’s memory to fill and possibly lead to a crash of the program and/or computer. It’s often desirable to have a set number of maximum iterations that if reached will guarantee the loop will exit. In this case, the functionality of a while loop can be replicated with the combination of a for loop and an if statement with a break keyword. For example, the while loop structure above is replicated in the following code, but with the guard that the maximum number of iterations cannot exceed 10.

for i = 0:10
    if i > 4
        break
    end
    println(i)
end
0
1
2
3
4