Web Development With HHVM and Hack 8: Loops

Mike Abelar
5 min readMar 2, 2020

--

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

--

--