Web Development With HHVM and Hack 8: Loops
In the last tutorial, we covered functions: https://medium.com/@mikeabelar/web-development-with-hhvm-and-hack-7-functions-7a0f56023324. In this tutorial, we will cover loops in Hack.
What Are Loops?
Loops allow us to repeatedly run some chunk of code based on certain conditions. When we covered vectors and dictionaries, we saw examples of loops for vectors and dictionaries respectively:
<<__EntryPoint>>
function main(): noreturn {
// code here
$names = vec["mike", "joe", "bill"];
foreach ($names as $name) {
print($name . "\n");
}
exit(0);
}<<__EntryPoint>>
function main(): noreturn {
// code here
$words = dict[
"gobbledygook" => "gibberish",
1 => "surprise"
];
foreach ($words as $word => $definition) {
print("Word: " . $word . " Definition: " . $definition . "\n");
}
exit(0);
}
In both examples, we repeat the same code (printing the contents of the vectors and dictionaries) for a certain number of times. This number is determined by the size of the vector and dictionary because we are looping over each element using the foreach
loop.
Other Types of Loops
The foreach
loop is one type of loop. Let’s explore other types of loops. To do so, create a folder and inside the folder create a hhconfig file:
touch .hhconfig
Then, let’s create a hack file to explore loops:
touch loops.hack
The For Loop
Here is an example of a for loop (you can put this code in loops.hack
and run it with hhvm loops.hack
after checking the code with hh_client loops.hack
):
<<__EntryPoint>>
function main() : noreturn {
for ($i = 1; $i <= 5; $i++) {
print($i);
print("\n");
}
exit(0);
}
The code will print:
1
2
3
4
5
We can see that this code is printing 1 through 5. The body of the code makes it clear:
print($i);
print("\n");
But how is it doing this? Let’s start by looking at the for loop:
for ($i = 1; $i <= 5; $i++)
We declare a for loop with the for
keyword. Inside the for loop, we see three pieces of code, separated by semicolons. Let’s take this code piece by piece:
$i = 1
We declare a variable called i
and set it equal to 1.
$i <= 5
This next piece of code is the condition. We are evaluating if i
is less than or equal to 5. If this code is true, then we execute the body of the for loop. Otherwise, the for loop ends. Therefore, in this case, we print i
.
$i++
This next code updates/changes i
for the next iteration.In this case $i++
means increment i
by one.
Now that we understand the various pieces of the for loop, let’s take a look at the execution of for loop to understand these pieces together:
Execution of the for loop
Iteration 1:
Value of i
: 1
Condition: $i <= 5
: this is true
Body: Because the condition is true, we print the code.
Change: increment i
by 1.
Iteration 2:
Value of i
: 2
Condition: $i <= 5
: this is true
Body: Because the condition is true, we print the code.
Change: increment i
by 1.
Iteration 3:
Value of i
: 3
Condition: $i <= 5
: this is true
Body: Because the condition is true, we print the code.
Change: increment i
by 1.
Iteration 4:
Value of i
: 4
Condition: $i <= 5
: this is true
Body: Because the condition is true, we print the code.
Change: increment i
by 1.
Iteration 5:
Value of i
: 5
Condition: $i <= 5
: this is true
Body: Because the condition is true, we print the code.
Change: increment i
by 1.
Iteration 6:
Value of i
: 6
Condition: $i <= 5
: this is false
Body: Because the condition is false, the for loop ends.
Breaking For Loops
Sometimes, we may want to end a for loop early. Consider the example of wanting to find the largest square (a number times itself) that is less than 24. We think that the square root of this square will be less than 10 so that is what we iterate over. However, we want to stop once we find the largest square less than 24. Here is how we would do this:
<<__EntryPoint>>
function main() : noreturn {
for ($i = 1; $i < 10; $i++) {
if ($i * $i >= 25) {
print($i - 1);
print("\n");
break;
}
}
exit(0);
}
Notice that once we hit a square that is not less than 25, we print the square root of the square (the previous value of i)
and then use the word break
. This will end the for loop such that no further iterations will run.
Note: if you return a value in the for loop, this will also end the for loop early because no code is run after return
.
Continue
Say we wanted to print all even numbers less than 10. One way to do this is to modify the update/change code in the for loop:
<<__EntryPoint>>
function main() : noreturn {
for ($i = 0; $i < 10; $i = $i + 2) {
print($i);
print("\n");
}
exit(0);
}
which prints:
0
2
4
6
8
Or, we can use continue
, which stops the current iteration of the for loop and goes to the next iteration:
<<__EntryPoint>>
function main() : noreturn {
for ($i = 0; $i < 10; $i = $i + 2) {
// checks if number is odd
// if so, go to the next iteration
if ($i % 2 == 1) {
continue;
}
print($i);
print("\n");
}
exit(0);
}
Therefore, when i
divided by 2 leaves a remainder of 1, we just move on to the next iteration and do not reach the print
statements.
While Loops
While loops allow you to continuously run code while a condition is true/until the condition is false. Here is code printing 1 through 5:
<<__EntryPoint>>
function main() : noreturn {
$i = 1;
while ($i <= 5) {
print($i);
print("\n");
$i = $i + 1;
}
exit(0);
}
Here, we define i
to be one. While i
is less than or equal to 5, we run the code in the body of the loop. During each iteration, we increment i
by 1. Therefore, i
will eventually be 6 and the code will stop.
Note: It can be easy to fall into the trap of having your while loop never exit the loop. Make sure that your condition will eventually be false.
In the next tutorial, we cover tuples: https://medium.com/@mikeabelar/web-development-with-hhvm-and-hack-9-tuples-d2f14126a2eb