Loops in Lua

Note: this page has lots of examples. You will not follow what is going on unless you try them all out, so regard it as implicit after each example that there is an exercise that says "Try it out and make sure you see what is happening."

1. Introduction

In previous pages in this sequence you have seen how to

This page introduces you to a few more ways of writing Lua programs! and sets a few tasks for you. In particular you will see more about the "for" loop and the the "while" loop. The objectives are to give you a very basic flavour of each of these, not to explain how to become an expert Lua programmer. If that's what you want to do, then you will need to read the manual. ("RTFM" is a standard Computing acronym. It is short for "Read The Manual":)

All of the programming in Lua described on this web page has analogues in just about any other standard "imperative" programming language such as C++, Java, C# etc. It will take very little time to convert what you learn about Lua to some other language.

2. The "for" loop

(While you are working through this section, try the examples out in Lua. Most likely you can try everything out using Lua in interactive mode. Make notes for anything that you think you might need and not be able to remember. Don't forget that computer syntax is very precise, so for example a semicolon is not the same as a comma and the different kinds of brackets have different meanings.)

You have seen the "for" loop. An example is,

for a=1,100 do
  print(a,a*a)
end

Of course if you want to start at a different place (instead of 1) or finish somewhere else, you just change the numbers.

Try it now.

If you want to loop going up in steps of a different size, you just add a third value in the "for" line.

for a=2,200,2 do
  print(a,a*a)
end

What happens if the value of a doesn't hit the upper bound exactly? As in "for a=1,200,2 do ... end"? Find out by testing it.

If you want to make the value of a go down rather than up just use a negative step. In this case the second value is the lower bound, not the upper bound.

for a=100,1,-1 do
  print(a,a*a)
end

(Important.) What do you think happens in the next example?

for a=1,100,-1 do
  print(a,a*a)
end

Lua's "for" loop has a two or three of features that should be regarded as Very Good Things that are not in every programming language. For completeness, and so you don't get confused, we mention them here. The first is that sometimes the "body" of the loop doesn't get executed at all. (This is indeed what you usually want in such cases.) The next is that the variable in the loop is "local" to the loop:

a = 57
for a=1,100 do
  print(a,a*a)
end
print(a)

There is a special variable a that is introduced just for the loop that is different to the other variable a. This is the programming equivalent of dummy variables that you might have seen discussed in tutorials.

The consequence of this is that the "old" value (of a, i.e. 57 here) is not available inside the loop. If that's a problem, use a different variable name.

The other nice feature of Lua's "for" loop is that the limits are evaluated only once.

b = 57
e = 60
for a=b,e do
  print(a,a*a)
  print("e = ",e)
  e = 58
end
print(e)

Here you might have thought that changing the way that the variable e that defines the end-point of the loop will change the way the loop works. In Lua that is not the case, because the end points "b,e" are calculated only once when the loop starts, and are not re-calculated.

This is a nice feature of Lua that, once again, does what you want most of the time. The "for" loop in C++ does not have this feature, though there are ways to get something equivalent.

Of course the inside (or "body") of a "for" loop can be almost anything, including another "for" loop.

Exercise: write a Lua program that first sets the variable i to be 5 and then computes the sum j = i 10 j .

Hint: you will need a new variable for the "running sum". Whatever you call it, initialise it to zero.

Exercise: write a Lua program to compute the sum i = 1 10 j = i 10 j from the tutorial sheet. Check your answer against the calculation you did for the tutorial.

Hint: You will need a "for" loop inside another "for" loop.

3. The "while" loop

Lua, like most languages can determine if a statement is true or false. The most common kind of true/false statement is whether a variable equals some value or not. But, like most languages, Lua has taken the symbol = to mean something different (i.e. "take the value on the right and put it into the variable on the left"), so we can't use = to mean "equals".

This is a very very common trap for all beginners to most programming languages. Be very careful that you do not write = for "equals".

Instead, Lua (like most languages) uses == to mean equals:

> x = 1
> y = 2
> print ( x==y )
false
> z = 1
> print ( x==z )
true
> print ( x=y )
stdin:1: ')' expected near '='

Other relations that are commonly used are < > <= >= and ~= for "not equals".

> print (x < y )
true
> print (x > y )
false
> print (x ~= y )
true
> print (x <= y )
true
> print (x >= y )
false
> print (x >= z )

Be careful: there seems to be no standard for what character combination should be used for "not equals". The C++ language uses != and others use <> but in Lua you must use ~=.

These operations work on strings too.

Exercise: explain the result you get with "print("12"<"3")".

With this preliminary out of the way I can now explain the "while" loop, which is the other main type of loop. This one tests a condition each time it goes round the loop.

a = 1
while a < 100 do
  print( a )
  a = a+1
end

As you can see it is possible to use "while" to make loops rather like "for" loops. But they can do a number of things that "for" loops cannot do.

Before we get on to that, however, you need to be sure of what to do when things go wrong. Suppose I had written,

a = 1
while a < 100 do
  print( a )
end

then the loop goes on for ever and the computer will not stop. So what should you do?

In fact this was mentioned earlier, but it is now important. The answer is to press "control-C" to stop. Try it now.

> a = 1
> while a < 100 do
>> print(a)
>> end
1
1
.
.
.
1
1
1
1
1
1
1
1
1
^Cstdin:2: interrupted!
stack traceback:
	[C]: in function 'print'
	stdin:2: in main chunk
	[C]: in ?
>

This is one of the things "while" can do that "for" cannot. With "while" you can make loops that go for an arbitrary length of time, or even forever. With "for" all loops are bounded at the moment they are started.

The other thing that "while" can do is change the conditions of the loop in the middle of the loop, should you really want that. Here is a version of a previous example.

b = 57
e = 60
a = b
while a <= e do
  print(a,a*a)
  print("e = ",e)
  e = 58
  a = a+1
end
print(e)

Work through what it does step by step. It should all be straightforward!

Another trap for beginners and others alike, is forgetting to change values in a "while" loop to let the loop halt. For example forgetting "a = a+1" in the above will prevent the loop stopping.

"While" loops, like "for" loops, need not execute their body at all.

b = 57
e = 60
a = e
while a <= b do
  print(a,a*a)
  a = a+1
end

Exercise: re-write your program for the sum i = 1 10 j = i 10 j using "while" loops instead of "for" loops.

Finally, the Fibonacci numbers are the familiar numbers 0,1,1,2,3,5,8,13,21,... where each is the sum of the previous two.

Obviously, to make z equal to the sum of x, y you just write "z = x + y" in Lua. This is the basis of a Lua program for the first 100 Fibonacci numbers. But we will also need a loop counting up to 100.

n = 1
x = 0
y = 1
while n < 100 do 
  ...
end

Here, I have initialised n to 1 and x,y to be the first two Fibonacci numbers.

Exercise: complete this program to print the first 100 Fibonacci numbers. You'll have to put code that modifies the variables x,y,z,n in the space for ..., as well as printing one of these numbers out.