Instructor's Manual for

M.B. Feldman and E.B. Koffman, Ada 95 Problem Solving and Program Design, 3rd edition. Copyright 1999, Addison-Wesley Publishing Company. All Rights Reserved

Questions and comments to mfeldman@seas.gwu.edu


Chapter 7 Other Loop Forms; Procedures; Exception Handling

last revised March 1999

Chapter Objectives

The student will

  1. learn the syntax and semantics of the LOOP-EXIT and WHILE structures
  2. learn how to construct sentinel-controlled loops and flag-controlled loops
  3. learn how to write simple procedures
  4. learn how to write a simple child package
  5. learn how to write robust input programs using exception handling

New Terms

Section 7.1

LOOP statement

EXIT statement

Section 7.2

flag-controlled loop

sentinel-controlled loop

priming read

 

Section 7.3

WHILE statement

Section 7.4

exception-handling loop

block

Section 7.5

procedure specification

procedure body

IN mode parameters

OUT mode parameters

IN OUT mode parameters

preconditions

postconditions

 

Section 7.6

robust interactive input

 

Section 7.8

nonhalting programs

 

Section 7.10

child package

 

Notes and Suggestions

The material on loops other than FOR loops is heavily revised in this edition, to present general loops before WHILE loops. This reflects the observation that beginners deal more naturally with "positive logic" -- stating a positive condition to exit a loop -- than with "negative logic" -- stating a negative condition to exit a loop, which continues the loop while the condition is true.

Section 7.1

The general LOOP-EXIT combination can be used to implement test-at-top, test-at-bottom, and test-in-middle loop structures.

General loops are more difficult to use correctly than FOR loops. Emphasize that the loop continuation test is done before the loop body, and so it is possible for the loop body to execute zero times. Because the condition must be well-defined before the loop body is entered the first time, it is essential that all variables occurring in the exit condition be initialized.

An especially important use of the general loop is in writing robust input loops, which is taken up in section 7.4.

Be sure students understand that failure to include a loop incrementation statement within the loop body will result in an infinite loop, which may be difficult to break out of on a PC without resetting it.

Section 7.2

Loop design is often difficult. Emphasize the loop templates for flag-controlled and sentinel-controlled loops, and the role of the priming read in the latter. Be sure students get practice in designing loops, paying attention to (a) getting the initial conditions right, (b) making sure that progress is made toward termination, and (c) getting the loop to stop at just the right time.

Section 7.3

In this section the WHILE loop is readily seen to be a special case of the general loop, with the test at the top and negative logic. Students with Pascal or C experience will wonder why Ada has a WHILE statement but no REPEAT statement. Indeed, I've always wondered that myself.

Section 7.4

An input loop with an exception handler will be a most unfamiliar structure to almost everyone. Spend some time discussing the templates on p. 268 and p. 269. Be certain the following principles are understood: (1) an exception handler is always associated with a block; (2) within a procedure, a block can have as large or as small a scope as one desires; (3) the LOOP occurs outside the block, so that the block is re-entered at every iteration of the loop; (4) the EXIT statement causes exit from the loop upon receipt of valid input.

Also discuss the reason for the Skip_Line statement in the exception handler of program 7.6: The input buffer must be cleared to prevent an infinite loop. This is a consequence of numeric and enumeration input ceasing at the first character not part of the desired token, leaving this character in the buffer to be read by the next Get. There are "industrial-strength" solutions to this problem that do not require flushing the input with a Skip_Line, but they are really beyond the scope of this text.

The case study in this section provides the skeleton for a robust menu handler, which students can adapt to fit the needs of a project. I generally assign at least one project that requires adapting this program.

Section 7.5

Procedures with parameters are difficult for beginners to learn, and it is important to show many illustrations of how parameters are transmitted. We believe that named association makes learning parameters somewhat easier, because the name of the formal parameter is always seen paired with the actual parameter.

Ada's parameter modes are interesting in that they de-couple the use of a parameter from the implementation concern of how the parameter is transmitted. Students with Pascal or C experience will be surprised that an IN parameter is not the same as a value parameter. Within the body of the procedure an IN parameter is read-only (this is enforced by the compiler).

Teachers with Ada 83 experience will recall that OUT parameters were write-only and therefore caused much grief for beginners. In Ada 95, OUT parameters can be used freely within the subprogram. It is therefore relevant to point out the difference between OUT and IN OUT parameters. The value of an IN OUT actual parameter is passed to the procedure; that of an OUT parameter is not.

The point is to emphasize that students should not be concerned with how a parameter is passed; rather, they should decide, based on the program requirements, how parameters are used.

Procedures and functions in the sequel are almost always given with preconditions and postconditions as comments. Discuss the use of these as another sort of contract with the caller of the procedure: If the preconditions are met upon the procedure call, the procedure will guarantee the postconditions. Preconditions are generally conditions that cannot be easily tested--whether variables are initialized, for example. Since the procedure cannot usually test the preconditions, "all bets are off" if they are violated by the caller.

Section 7.6

Go over the body of the robust input package carefully with your students; it is a useful example of exception handling loops.

Section 7.7

One important purpose of our introductory courses is to plant the seeds of professionalism and high regard for the users of one's software creations. One aspect of this is robustness, which we take to mean that a program should not "crash" unexpectedly. We are all irritated by software products like word processors that occasionally freeze or crash our personal computers; most students will have experienced this irritation. This tells us that perfection in software is very difficult to achieve, but it is a goal toward which we should all strive with pride.

I therefore recommend that a unit on exception handling should reinforce the "principle of predictable performance," which dictates that a program should behave predictably even in the presence of ill-formed or out-of-range inputs. This is a language-independent concept: Whether or not one uses Ada's exception handling, one is responsible for trying to ensure predictable performance. A professional should make one's best attempt, because tragic situations--the Therac-25 radiation machine comes to mind--can arise out of mishandled stray input keystrokes.

At the end of this unit, students know enough Ada to write programs whose input operations are robust and "bulletproof." I encourage teachers to require that subsequent programs be robust, and that students' test plans and test results demonstrate robustness. I require this in my course.

Section 7.10

Child packages in Ada 95 provide a mechanism for extending the contents of a package without touching the original. A child package is not the same as a client of a package: A child can see into its parent's private section, while a client cannot. Private types are not a major issue in first-semester courses, but it is important not to encourage poor design habits. Child packages must therefore be reserved for situations in which, in effect, functionality is to be added to the parent package.