Cooking with Code: Mix until combined (or using While and Do-While loops in Apex & Java)

Loops are like a recipe instruction of "Mix until combined."

Welcome back to another episode of Cooking With Code, where I tempt you with food-inspired introductions to Object-Oriented Programming (OOP) concepts.

In previous posts, you’ve learned that Apex and Java, like other OOP languages, have basic building blocks or tools to help us program. Examples include: classes, objects, methods, and variables (both primitive and collections).

This blog post will introduce another cool Apex/Java tool to our coding kitchen: the loop. Loops are great because they allow you to take a piece of your code and repeat it over and over again. Neat right?!

Apex and Java have four types of looping tools,* and this post will talk through two of them:

  • While loops
  • Do-While loops

Luckily, the syntax for both of these types of loops is the same in both Apex and Java, which is great because you’ll love telling people you’re learning not one, but two languages (like hitting two balls with one swing).

OMG, this is going to be SO MUCH FUN!

* I’ll be covering the other types of Apex loops – For and For-Each loops – in a subsequent blog post.

What is a Loop?

At their most basic level, loops are pretty simple. They allows us to do something over and over again.

Yummy Pavlova!For today’s program, I’m using coding examples from one of my favorite desserts from my birth country, New Zealand: Pavlova. This is basically a massive meringue, but better than any meringue you’ve ever tasted. Crunchy on the outside, soft and fluffy in the middle, caramelized on the bottom, with whipped cream and fruit on the top. If you’ve never had one, you can’t imagine how divine they are (I’ve included the recipe on my resources page because I want to hear back if you agree).

Anyway, like most meringues, they are basically a bunch of egg whites and sugar, with a few other ingredients. But there is a secret to a great Pavlova, which is once you’ve beaten the egg whites until they’re stiff, you need to add the sugar excruciatingly slowly. My mum (who makes the most amazing Pavlovas eva!) adds the required cup of sugar a tablespoon (tbsp.) at a time, at one minute intervals. (Can’t you hear the coding scope starting to write itself!)

My kitchenaid is very loud!I’ve made it myself more than a few times, and when I’m adding the sugar, and my Kitchenaid mixer is blaring at a deafening volume, I’ve often thought…wouldn’t it be nice if I could set this section on autopilot and not have to be there to do it. My ears sure would love that!

That’s what loops can do for us. Ooohhhh! Ahhhhh!

Two loops: 1 for beating the egg whites until stiff, the other to add 1 tablespoon of sugar 16 times.There are actually at least a couple of different loops within this recipe: one focusing on how long we need to beat the egg whites for (until they are stiff) and another targeting the addition of the sugar.

In pseudo code, the loops would be something like this:

// Declare an Integer variable called portionsOfSugar and set it to 16 (there are 16 tablespoons in a cup)
// Declare a Boolean variable called areEggWhitesStiff and set it false
// Loop One: Beat the egg whites until egg whites are stiff
// Loop Two: Add a tablespoon of sugar every minute until there is no sugar left to add
// Cook it
// Eat it (yum!!)

In the loops above, we can use two of the three different types of loops that come with Apex (While and Do-While loops).

Let’s check them out!

While and Do-While Loops

For the sake of explaining the different types of loops, we’re going say that the first loop (beat egg whites until stiff) is a While loop and the second (add sugar gradually) is a Do-While loop.

While LoopWhile and Do-While loops are pretty similar. They both:

  • Look to see if a particular condition is met (e.g., If egg whites are not stiff. If there is still sugar left to add.), and while the condition is met,
  • Do something (keep beating or adding sugar).

The main difference, is when they look for the condition to be met. I’ll get into this in the examples below, but While loops check for the condition before the loop starts, and Do-While loops check for it after the first loop has completed.

Do-While LoopThis may seem like a trivial matter, but it can have pretty big consequences. The difference is that a Do-While loop always runs at least once, while a While loop might never run (depending on the condition that we’re using).

Kind of like the difference between that obnoxious, but funny, friend who we “can’t take anywhere,” (While loop) vs “can take anywhere…once” (Do-While Loop).

Lost you? Perhaps I should stick to cooking metaphors…never mind…stay with me because the examples below are better. (I promise!)

Syntax of a Basic While Loop

A basic While loop is pretty simple and has the following structure:

While (some condition is met) {
// Run this block of code
}

Everything between the two curly braces is the block of code that will run with every iteration of the loop.

Beat Egg Whites While LoopIn our egg white beating example, it could look like this:

// Create a Boolean variable and set it to false
Boolean areEggWhitesStiff = FALSE;

//Start the loop, while the egg whites are not stiff, beat them.
While (areEggWhitesStiff == FALSE){

     // Block of code that will repeat.
     // In this case a method that will beat the egg whites for 10 seconds
     beatEggWhites();

     //and then call another method to checks if the egg whites are done.
     //If they are, then it sets the areEggWhitesStiff variable to TRUE
     checkIfEggWhitesAreStiff();
}

 Comparison Operators

The code above is probably fairly straightforward, except perhaps the bit where we write areEggWhitesStiff == false (line 5). Perhaps you wondered if I made a mistake and put in two equals signs instead of one? Nope, that is exactly what we need here.

Comparison Operator in action

In coding terms, == is asking the question, “Is the left side of me equivalent to the right side of me?

So in our case, “Is the value of boolean variable areEggWhitesStiff equivalent to ‘false’?“

The following symbols (operators) are all comparison operators, whose whole job is to compare the stuff on their left to the stuff on their right:

Operator What it does Examples
(all would be true statements)
< Less than 10 < 11
<= Less than or equal to 10<=10
9 <= 10
== Equal to 10 == 10
!= Not equal to 10 != 11
> Greater than 11 > 10
>= Greater than or equal to 11>= 10
10>= 10

 

Why didn’t I use just one equals sign? Because in Apex (and Java) a single equals sign is an assignment operator, which means we use it to assign a value to a variable, for example:

X = 10 +1 //this means that x really equals 11

Back to our While loop…

When we last left our kitchen code it looked like this:

// Create a Boolean variable and set it to false
Boolean areEggWhitesStiff = FALSE;

//Start the loop, while the egg whites are not stiff, beat them.
While (areEggWhitesStiff == FALSE){

     // Block of code that will repeat.
     // In this case a method that will beat the egg whites for 10 seconds
     beatEggWhites();

     //and then call another method to checks if the egg whites are done.
     //If they are, then it sets the areEggWhitesStiff variable to TRUE
     checkIfEggWhitesAreStiff();
}

What happens when the While loop condition is false from the starts The loop never plays.So what we’re doing here is checking to see if the egg whites are stiff, if they’re not, we continue to beat them.

But what if we had a Sous Chef (aka your spouse or child) and they had already beaten the egg whites to a stiff peak for us? Would we go through any iterations of the loop?

Nope, we would skip this loop completely, because the condition would not test as correct (e.g., areEggWhitesStiff would equal ‘true’ not ‘false’).  So we’d skip that loop and move on to the next. How convenient!

Let’s look at how the While loop compares to the Do-While loop.

Syntax of a Basic Do-While Loop

Add Sugar Do-While LoopAs mentioned above, both the While and Do-While loops allow us to:

  • Loop through code
  • Test a condition to control how many times we repeat the loop

So how do they differ? Let’s look at the basic syntax of a Do-While loop:

do {
    // Run this block of code
} while (some condition is met);

As you can see, the “DO” code block to be repeated is stated before the While condition, and therefore the code block is always run at least once.

In our sugar example, this would look something like this:

//create an integer variable representing how many portions we want to break our cup of sugar into
Integer portionsOfSugar = 16;

//Start the loop, everything between the curly braces is repeated
Do {
    //add a tablespoon of sugar
    addSugar();

    //reduce the integer variable by 1
    portionsOfSugar --; //Say what! What does ‘--‘ do?

// while the integer variable is greater than zero, keep looping
} while (portionsOfSugar > 0);

Post-Increment/Decrement Operators

You probably spotted something pretty different in the code above; look at line 10 to the last bit of the looping code block:

portionsOfSugar--;

This is a Post-Decrement Operator, which is a fancy way of saying, “decrease the portionsOfSugar Integer value by 1.” There is a matching Post-Increment Operator, which would look like this:

portionsOfSugar++;

Yep, you guessed it! This increases the value of portionsOfSugar by 1. You see these a lot in Do-While and While loops, because they save us work. The code above, written out the long way looks like this…

portionsOfSugar = portionsOfSugar + 1;

…but doesn’t that seem like a lot of typing? I’m too lazy efficient for that.

But back to our Do-While loop…

What we’re doing is setting a variable to help us count the number of times that we want to loop through and add sugar. If I would write out what is happening in each loop, it would look something like this:


Before the loop begins: Set the portionsOfSugar variable to a value of 16


Loop 1: Add 1 tbsp sugar, then reduce portionsOfSugar by 1 (new value=15)
      Q: Is the portionsOfSugar greater than zero?
      A: Yes… so loop again

Loop 2: Add 1 tbsp sugar, then reduce portionsOfSugar by 1 (new value = 14)
      Q: Is the portionsOfSugar greater than zero?
      A: Yes… so loop again


“We will now break for a message from our sponsor” … this is where we save you from sitting through loops 3-14 and don’t bore you into changing channels. Nooo….don’t leave us!


Loop 15: Add 1 tbsp sugar, then reduce portionsOfSugar by 1 (new value = 1)
      Q: Is the portionsOfSugar greater than zero?
      A: Yes… so loop again

Loop 16: Add 1 tbsp sugar, then reduce portionsOfSugar by 1 (new value = 0)
      Q: Is the portionsOfSugar greater than zero?
      A: No…we have added all the sugar and can turn off our mixer
           (phew…my poor ringing ears!)


The loop ends: We have now added all the sugar we need.


But why would we use a Do-While loop, instead of a While loop?

Pavlovas need sugarPavlova tastes terrible without sugar, so we wanted to make sure that sugar got added, regardless of the portion size. So in that way, we would want to run through the loop at least once.

But to be honest, that’s stretching the example a little too far, because I could quite easily have written the sugar example as a While loop, and have it behave as we expect. I believe it would even be easier to read; see below what that code would look like.

//create and integer variable representing how many portions we want to break our cup of sugar into
Integer portionsOfSugar = 16;

//Start the loop, while the number of sugar portions are greater than zero, then add sugar.
While (portionsOfSugar > 0){

    // Block of code that will repeat.
    // In this case a method that will add sugar.
    addSugar();
    portionsOfSugar--;
}

Better example of a do-while loopAn example that is probably more apt, is perhaps we want to collect some input (a number) from the user, and then check to see if the input is within bounds of some criteria (was a positive value). If the number is positive, then we use the input to do something and end the loop. If the number is negative, then we ask again. We would use a Do-While loop to achieve this, because we’d want to ask the user for input at least once.

There are no hard and fast rules about whether to use a Do-While vs a While loop, but generally, I use the following guidelines:

  • If I want the code to run at least once, regardless of the condition then I use a Do-While loop
  • Otherwise I use a While loop

While and Do-While Loops–A Cautionary Tale

So by now you’re pretty excited by these loops, right?! I totally get it, and I’m all for your enthusiasm, but it’d be remiss of me if I didn’t temper your eagerness with a tale of potential woe. <Cue foreboding music> With great power comes great responsibility (and I’m talking about your power, not mine).

What do you think would happen if you ran the following code?

Integer portionsOfSugar = 16;

While (portionsOfSugar > 0){
    addSugar();
}

Can you see where the problem is? Here’s what we’re saying:

  1. Set the portionsOfSugar variable to 16
  2. While portionsOfSugar is greater than zero then loop through:
    1. Merrily adding sugar

An infinite loop in actionCan you spot what we’re missing? Take a look at the criteria for the loop (line 3) and the value of portionsOfSugar (line 1); is it ever going to get to zero?

If our portionsOfSugar variable starts with a value of 16, and we never decrease it, then its value will always be greater than zero.

What we have here is an Infinite Loop. That is, a loop that never stops. If we ran this in our Code Kitchen, we’d eventually break our expensive Kitchenaid because we’d overloaded the motor with too much sugar (and never turning it off). We’d also be very, very unhappy because our Pavlova would be ruined! So very, very sad!

In order to stop an infinite loop situation, we need to add some way to decrement the value portionsOfSugar, so that eventually fail the looping criteria, and the loop will stop (see line 5):

Integer portionsOfSugar = 16;

While (portionsOfSugar > 0){
     addSugar();
     portionsOfSugar--; //this decreases the value of the variable by 1 with every iteration of the loop.
}

So the danger with While and Do-While loops is you much always put in an escape hatch by building in a way to stop the loop. Normally this is done by:

  1. Setting a variable before the loop starts
  2. Setting a condition that tests for the value of the variable
  3. Increment (or decrement depending on your condition) the value of the variable, so that after the specified number of iterations your loop will stop.

There are other loops (For and For-Each Loops) in Apex, that don’t have this kind of problem. In a future post I’ll take a introduce them, and take inspiration from Kevin Poorman and James Loghry’s fabulous Dreamforce presentations on the Apex 10 Commandments, in which they devote two commandments for what not to do in For Loops. If you haven’t listened to it already, I suggest checking out a recent CodeCoverage.org Podcast (Episode 18 – Kevin Poorman and the Apex 10 Commandments).

Summing up

Yummy Pavlova!In this blog post I’ve introduced you to two of the four looping tools available to both Java and Apex: While and Do-While loops.

The most important things to remember are:

  • Both allow you to repeat a block of code.
  • Both allow you to test a condition to control how many times to repeat the code:
    • Conditions that test TRUE trigger an iteration of the loop.
    • Conditions that are FALSE do not trigger an iteration of the loop.
  • While loops test the condition before the loop runs. This means if the condition is false before the first loop, then the loop will never run.
  • Do-While loops test the condition after each round of the loop completes. This means they always run at least once.
  • Always build in an escape hatch (a way to stop the loop) so you don’t create an Infinite loop.

We also learned about:

  • Comparison Operators:
    • <, <=, ==, !=, >=, > which compare stuff on their left, to stuff on their right, and come back with a Boolean value (e.g., True, or False).
  • Assignment Operator:
    • A single equals sign (=) is used to assign a variable on the left, the calculated value from the right (e.g., x = 1+1).
  • Post-Increment/Decrement Operators:
    • variableName++ increases the value of an Integer variable by 1
    • variableName-- decreases the value of an Integer variable by 1

I hope you enjoyed this field trip into the exciting world of While/Do-While loops. I’m glad you joined me!

Until next time…Bon Appétit!