Programming Languages (CSC-302 98S)
Outline of Class 17: More Control: Loops
Held: Monday, March 2, 1998
- I got back last night at midnight, and haven't even had a chance to
glance at your exams. It's likely that I'll collapse tonight, so I
won't have much chance to grade tonight, either. Do you have any
- I brought back some interesting software from the conference. Some
of it runs on PCs and is therefore useless to me. Feel free to stop
by and see if something is of interest.
- Today's brown-bag lunch has the intimidating title of
Windows NT Privileged Architecture. I have no idea whether
or not it will be interesting.
- Grinnell Women in Science is sponsoring two talks by Dr. Gene Mapes
this week. One is Wed. at 4:15 in the "wouth" lounge of the forum
(presumably South). At 8pm in Science 1023 she'll give a talk on
"Feminism and Science". There are further events on Thursday at
4:15 and 8.
- We had an example from the end of last class.
- Many algorithms also need a way to express repetition. It
is possible, but not elegant, to express repetition with conditional
- If a language does not provide some form of
repetition, then it is not Turing complete.
- Recursion plus conditionals provide one form of repetition.
- A particularly common form of repetition is the loop, which
repeats a statement some number of times.
- Loops provide an abstraction of repetition that can help ensure that
- We can only enter the repeated statements in one (or a few ways).
- We can only have one subsequent statement (one that follows the
- There are only a limited number of ways to exit the loop.
- Repetition also introduce some problems into the language. Once programs
can repeat parts, it becomes difficult (if not impossible) to prove that
a program terminates.
- There are two general kinds of loops:
for loops traditionally repeat a statement (or block
of statements) a fixed number of times.
while loops repeat a statement (block of statements)
an arbitrary number of times.
- For loops generally express a fixed number of repetitions
using a counter variable.
- For loops generally contain five components:
- A counter variable
- A starting value for the counter variable
- An ending value for the counter variable
- An increment to the counter variable
- A statement to execute
- One advantage of such loops is that they are easy to analyze at compile
- If the starting value, ending value, and counter are constants,
then we can know at compile time how many times the loop will repeat.
- We can unroll such a loop so that we never have to do a
test (or even a conditional jump).
- We can guarantee that the loop terminates.
- Some variants of for loops (e.g., those in Java and C) these
allow much more general components.
- For example, many
languages permit a termination condition rather than an ending
- Use of termination conditions obviate the aforementioned benefits.
- For loops also provide a natural way to express a number of algorithms.
- Even without the "extensions" of C and Java, there are a number of
design issues in for loops.
- The counter.
- What types are valid for counters?
- Can counters be accessed within the loop? (Usually yes.)
- Can counters be changed within the loop? (Usually no.)
- Is it defined after the loop exits? If so, how? (Usually
- The bounds.
- Are we restricted to constants, or can we use expressions?
- If we can use expressions, how often are they evaluated? (Only
at the beginning of the loop? Each time through? Something else?)
- Can we specify both bounds? Some loops only allow you to specify the
upper bound and start with 1 or 0.
- The body.
- Can one exit the loop from within the body?
- Is the body executed if the lower bound is "after" the upper bound?
- There are also a number of variants of for loops. One typical one
is the foreach loop, which steps through the elements in a
- While loops are loops that execute their body until a condition is
reached (rather than a fixed number of steps).
- They are more general than for loops, but the number of repetitions
usually cannot be predicted in advance.
- It is impossible to write a program that can read any
loop and determine whether the loop terminates.
- However, it is often possible to prove that particular loops
- I believe there are other cases in which we can't prove anything.
- As in each of the structures we have examined, there are many design
decisions. For example,
- Do you execute the body before or after the test?
- If you execute the test first, and it fails, do you still execute the body?
- Can you exit prematurely?
- Because of some of the analysis problems, it is particularly important
to carefully write loops using good design. This includes
- preconditions: what you know before you enter the loop (or any
statement within the loop)
- postconditions: what you know after you leave the loop
- loop invariants: some fact the loop maintains.
- We'll look at these in the context of binary search.
- Dijkstra's guarded loops generalize the guarded conditional to provide
- As with conditionals, guarded loops contain a number of guard/statement
- If no guards hold, the loop terminates.
- If one guard holds, the corresponding statement is executed.
- If one of the guards hold, one of the corresponding statements
- Exceptions provide an alternative form of control that extends
the "break" concept.
- In effect, exceptions allow us to abruptly exit a control structure
(loop, conditional, block, function, etc.) in such a way that we
don't necessarily move to the subsequent statement.
- In effect, exceptions provide two "subsequent" statements for each
statement. One is used for normal cases. One is used for exceptional
- In general, exceptions are used for error handling. There are
a number of possible errors/exceptions programs may encounter:
- Logic errors, such as division by zero or illegal array bounds
- I/O logic errors, such as illegal file names
- Serious errors, such as a filesystem becoming full or unavailable
- Mesages from other programs, such as interrupts
- It is possible to handle some of these using more verbose code
(test legality before executing, use some default value otherwise).
- However, it won't handle all types of errors (filesystems can
fill between the time it takes to check them and write).
- It also leads to less readable code.
- And few people bother to do it.
- CLU pioneered the use of exceptions (and many other interesting
control structures). Many modern languages (C++, Java, Ada95) include
exceptions because of their benefits.
- What design issues might we consider for exceptions?