Understanding Loops

There is a very short list of programming structures you have to learn to be reasonably comfortable in most modern object-oriented languages. Loops are one of them.

It’s a great idea to back up and read Understanding Arrays if you haven’t already. The reason is that Loops and Arrays go hand-in-hand. Loops are the interface we use to do interesting things with Arrays. You might think of Arrays as an mp3 player, and Loops as headphones … if you try to use either of these things separately, they may not seem too terribly useful. But put them together, and boy … beautiful music happens. Unless you’re listening to Nickelback.

That’s why the next article in this series is called Understanding Loops with Arrays. For now, just muscle through this article to understand what loops are all about – i’ll try to make it somewhat interesting. The beautiful music starts playing in the next article.

Pac Man

Your code is usually chewed through, line by line, by an interpreter. The interpreter is like Pac Man. It eats the first line, and carries out its instructions. Then it eats the second line and carries out those instructions and so on, until the end of your program. Earlier programming languages had each statement numbered, and the Pac Man code interpreter would chew through each one.

Commodore Basic

Goodness knows what “poke” meant in the cocaine-fueled days of the 1980’s.

Object-oriented programming (OOP) does away with those line numbers and sends Pac Man flying all over the maze a little bit, jumping into and out of chunks of code.

Pac Man Map

If procedural code with line numbers is like traveling by train on a straight track, OOP is like taking multiple plane flights through TIME PORTALS.

But imagine for a second that your Pac Man code interpreter has to eat straight down the page to the bottom, to the last line of code. If you want to do things more than once, you have to write the command more than once:

// This is pseudo-code, which means you can't really copy/paste it and expect it to work,
// but it's very readable.
eat a power pellet;
eat a power pellet;
eat a power pellet;

Fine. Pac Man eats a power pellet three times.

Hungry Hungry Pac Man

But what happens if your code interpreter needs to do something more than three times? Say, fifty times. Or a thousand? Now you’re going to have that same line repeated a thousand times down the screen. Yuck.

Or even worse, let’s say there are a number of instructions we want to carry out, and we want that set of instructions repeated:

// This is pseudo-code, which means you can't really copy/paste it and expect it to work,
// but it's very readable.
eat a power pellet;
give Ms. Pac Man a smooch;
punch a ghost in the face;
 
eat a power pellet;
give Ms. Pac Man a smooch;
punch a ghost in the face;
 
eat a power pellet;
give Ms. Pac Man a smooch;
punch a ghost in the face;

Now you’ve got a real problem. Your little set of instructions, repeated a thousand times, adds three thousand lines to the code – four thousand with line breaks. This code becomes ridiculous to manage and maintain, it looks ugly, and it takes up way too much room.

Enter that frustrated mom from every infomercial ever: “There’s got to be a better way!”

Plastic wrap is hard

Plastic wrap is HARD!

Loops are the better way. You build them to make the interpreter repeat an instruction, or set of instructions, a bunch of times. When the loop is done, the interpreter continues on its merry way down the page, chewing through each subsequent instruction you’ve written for it.

The Anatomy of a Loop

Here’s what a loop (often called a “for” loop) looks like in Actionscript 3 and other ECMA-based languages:

for(var i:int = 0; i<1000; i++)
{
}

Let’s break it down piece by piece.

You’ll notice there are two sections: the declaration line, and those curly braces.

Two main loop sections

The instructions you want to repeat go in between those curly braces, like so:

for(var i:int = 0; i<1000; i++)
{
    eat a power pellet;
    give Ms. Pac Man a smooch;
    punch a ghost in the face;
}

That declaration line looks pretty hairy, though. Let’s break it down.

Notice that the whole thing is just the word “for” followed by open and closed round brackets. If we completely gut the loop, it looks like this:

for()
{
}

Doesn’t look so scary any more, yeah?

The stuff between the round brackets is split up into three sections:

Loop header breakdown

  1. Start here.
  2. Keep looping as long as this is true.
  3. Do this after every run through the loop.

The first and second sections are separated by a semi-colon, which is the dot-above-the-comma symbol that we usually use to end our statements.

Names of common punctuation marks

1. Start Here

Loops start here

A “run” through a loop is called an iteration. In order to keep count of how many times we’ve looped, we use a variable called an iterator. Because the word “iterator” starts with the letter “i”, it’s common practice to use “i” as the iterator variable name.

So you need to declare and define that variable first, to give your loop a starting point. Depending on how picky your language is, you may have to type the variable (give it a datatype). Here are two examples of loops written in a permissive vs. strict language:

// Permissive, like Unity javascript:
for(i=0; i<1000; i++)
{
}
 
// Strict, like Actionscript 3:
for(var i:int=0; i<1000; i++)
{
}

So the only real difference is that in the stricter language, we had to declare the iterator variable using the “var’ keyword, and we had to expressly say that it was an integer datatype (whole number) by adding “:int” to the end of the variable name.

Note that you can also declare the iterator outside the loop, and define it inside the loop header:

var i:int;
for(i=0; i<1000; i++)
{
}

i like doing this, because it makes my loop header look cleaner. If i have more than one loop in my program, the compiler throws an error if i use the var keyword to declare the iterator more than once. That means that if i quickly copy/paste a loop where the iterator is delcared inside the header, the compiler yells at me:

for(var i:int=0; i<1000; i++)
{
}
 
for(var i:int=0; i<20; i++) // ERROR!  You've already declared a variable called i, dummy.
{
}

Meanwhile, this does not throw an error:

var i:int;
for(i=0; i<1000; i++)
{
}
 
for(i=0; i<20; i++) // No error. We're just resetting i to zero.
{
}

What this section does is set the value of a variable called i to zero. i is our counter that will keep track of how many times we’ve run through the loop.

Now, onto the second section of that confusing header.

2. Keep looping as long as this is true.

Loops keep looping

Every time the Pac Man interpreter starts to chew through this loop, he’s going to check the second section. This section tells him “you’re okay to chew through this loop, as long as this statement resolves to true.”

What do i mean by “resolves”? Imagine you take a bunch of ingredients and put them in a pan, and then bake what’s in the pan. You’ve resolved the ingredients into a cake. In the same way, we’re going to resolve the ingredients in this statement until they result in either true or false.

Here’s an easy one:

3<5 That statement resolves to true, because 3 is less than 5. But this statement:

3>5

resolves to false, because 3 is not greater than 5. These are the same rules we follow when we’re setting up conditional if statements. If you need a review, check out Understanding Operators, and Understanding Conditionals. (note: i haven’t written these articles yet, but they’re on the way!)

Things get a touch more complicated when variables are involved. Take this statement:

i<5 That's not as straightforward. i is the name of a variable (a bucket) that holds a value. Whether this statement resolves to true or false really depends on the value of i. If the value of i is 3, the statement resolves to true. But if the value of i is 867, the statement resolves to false. You can put all kinds of complicated nonsense into the second section of your loop header. Regard:

var i:int;
for(i=0; (i<1000 && theSunIsShining) || dogsLoveBacon(); i++)
{
}

In English, that second section now reads “run through the loop as long as the value of i is less than one thousand and the value of theSunIsShining is true, OR if the function dogsLoveBacon returns true.

Gross! Let’s keep it simple. When i was first learning programming, i’d sometimes write very complicated loop limiters, and i’d always regret it. It’s rare that you see anything beyond a simple i in this second section.

3. Do this after every run through the loop.

Loops do this after every iteration

The third and final section of the loop header tells the interpreter what to do after it chews through the last statement inside the curly braces of the loop. The interpreter gets to the bottom, does whatever is in the third section, and then checks the second section to see if it should run through the loop again. (If that’s confuding, don’t worry – we’ll take a closer look at that process in a moment.)

In most cases, this third section will say i++. That’s the increment operator, which is code shorthand for saying “add 1 to the value of i”. So every time through the loop, the counter goes up by one.

Again, you can make this bit crazy complicated if you like. You could say something like i+=Math.sqrt(beesHaveKnees()), which means “add the square root of the value returned by the beesHaveKnees function to the value of i”. You can even comma-separate multiple statements by saying i++, j++, which means “increment the value of i, and also increment the value of j”. You can do this, but in day-to-day vanilla programming, and especially just starting out, you’ll want to keep this stuff very, very simple.

Follow the Interpreter Through the Loop

So let’s trace the path of the Pac Man code interpreter through our loop.

Do the thing in the first section

1. Do what’s in the first section first. In this case, we set the value of the iterator variable i to zero.

Check the second section

2. Check to see if the second section resolves to true.

Chew through the statement block

3. If it does resolve to true, chew through all the statements in the statement block (the stuff between those curly braces). A power pellet gets eaten, Ms. Pac Man gets some lovin’, and a ghost gets his just desserts.

Execute the third section

4. When you finish chewing through the last statement in order, do what’s in the third section. In this example, we increase the value of i by one. The value of i (0) plus 1 equals 1, so the second time through the loop, i equals 1.

Check the second section again

5. Check the second section to see if it resolves to true. In our example, the value of i (1) is indeed less than 1000, so our interpreter should chew through all the statements in the loop body again. He eats another power pellet, plants another kiss, and dispatches another ghost.

Loop 1000 times

6. Let’s pretend we’ve gone through the loop 1000 times. Pac Man’s gluttony continues unabated, Ms. Pac Man struggles to cope with her husband’s relentless sexual advances, and his plan for spectral genocide is finally complete. At the bottom of the loop, the value of i is 999. (Note: it’s not 1000, because we started counting at zero)

Execute the third section

7. The interpreter jumps to the top of the loop header, and does what’s in the third section. Adding 1 to the value of i puts it at 1000.

Check the second section

8. The interpreter looks at the second section of the loop header to determine whether it should go through the loop again. This time, i is not less than 1000. (1000 is not less than 1000.) So because this statement resolves to false, the interpreter exits the loop, and continues after the closed curly brace at the bottom of the whole structure.

Exit the loop

9. Our Pac Man-like code interpreter exits the loop and smugly strikes a pose.

A Real-World Example

None of the code in this article will actually run properly, so here’s a chunk that will:

var i:int;
for(i=0; i<5; i++)
{
    trace("The value of i is " + i);
}

(If you want it to work in Unity javascript, change “trace” to “print” or “Debug.Log”, and you should see the results of the loop pop up in the Console window.)

As i mentioned off the top, loops on their own are very useful for keeping our programs down to a manageable size, but they really come alive when we combine them with Arrays. In the next article, Understanding Loops with Arrays, we’ll see how these two code constructs, when married, are a match made in programming heaven. And if we’re lucky, we’ll even see Pac Man tried as a war criminal. Join me, won’t you?

For more Flash AS3 Tutorials and a pile of other useful stuff, check out our Flash and Actionscript 911 feature.

10 thoughts on “Understanding Loops

  1. Pingback: untoldentertainment.com » Understanding Arrays

  2. Mark

    Even though I already know most of the things on your ‘basics’ tutorials, they are still incredibly enjoyable to read and explain things perfectly. Keep up the excellent work.

    Reply
    1. Ryan Henson Creighton

      Thanks so much, Mark. Why not share the article with someone you think might benefit from the info?

      Meanwhile, if you have requests for tutorials on more advanced topics, i’m all ears!

      Reply
      1. Mark

        Actually I do: the A* tutorial on here implements an interface for the nodes, however detailed explanations of these seem to be pretty scarce on the internet (or maybe I just didn’t look very hard).

        Reply
  3. Rasmus Wriedt Larsen

    Nice introduction to loops :) But, after “3. Do this after every run through the loop.” everything started to be in bold – you might want to look into that :P

    Also, your note on making “var i:int” before the loop header is fine. But I think it would be wise to clarify that you under no circumstances should make it a class variable. (as I did when I started out programming.. which resulted in some strange behavior).

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *