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 3 Introduction to Straight-Line Programs

last revised March 1999

Chapter Objectives

The student will
  1. be introduced to Ada through the use of small sample programs
  2. be shown the basic structure of an Ada program
  3. be able to discuss the predefined types Integer, Float, and Character
  4. be introduced to the predefined Ada 95 input/output (I/O) libraries Ada.Text_IO Ada.Integer_Text_IO, and Ada.Float_Text_IO
  5. be introduced to the formatting capabilities of the various Put statements in the I/O libraries
  6. be introduced to the assignment statement and basic arithmetic operators and simple expressions
  7. understand, at a basic level, the difference between syntax, semantic, and execution errors
  8. be able to write simple programs that perform input, output, and simple "straight-line" computations

New Terms

Section 3.1

body executable statements
declaration context clause (WITH)
reserved word identifier
program package
input statement output statement

Section 3.2

Integer I/O Float I/O

Section 3.3

constant variable
comment banner comment

Section 3.4

blank lines in programs  

Section 3.5

case study  

Section 3.6

assignment statement arithmetic operator

Section 3.7

output formatting prompting messages

Section 3.8

data type predefined data type
literal subtype
expression token

Notes and Suggestions

General Suggestions

You should require good programming style in all programming exercises, and be certain that your own sample programs follow the style of the programs in the book, to avoid confusing the students. Students without programming experience will follow your lead without objection; students with experience in another language, especially BASIC or FORTRAN, will tend to object to the indentation, capitalization, and whitespace conventions.

In discussing syntax and semantic errors, it is helpful to show students examples of compiler listings with mistakes such as forgetting the WITH statement or omitting a semicolon. Figure 3.7 is illustrative but specific to one compiler. It is instructive to show some listings from the compiler used for the class; the error messages are similar in content but different in form from one compiler to another.

Section 3.1

The beginning student is often confused about the difference between reserved words and identifiers, especially predefined identifiers like Put. The difference is visually apparent in our capitalization convention.

Students with experience in Fortran, BASIC, or Pascal might be surprised that Ada's input/output commands are just library procedure calls. Should they ask why this is so, explain that many modern languages such as C and Modula-2 also use libraries, and that this is done to provide the flexibility to expand the I/O capabilities without changing the language syntax. You might illustrate the importance of the context clause (WITH) by showing a compiler listing for Program 3.1 with the WITH statement removed.

Section 3.2

Teachers of Ada 83 know that it was difficult to motivate generic input/output for numerical quantities. Many solutions were found, none ideal. Ada 95 solves the problem in a standard fashion: the packages Ada.Integer_Text_IO and Ada.Float_Text_IO are now provided in the standard libraries. The entire Ada 95 standard library structure is both more elaborate and easier to explain than that of Ada 83.

One useful feature is that all standard libraries are child packages of the package Ada. This is helpful in showing students how to distinguish between standard packages and others in the book, or indeed those you might provide. If the package name begins with Ada., it is a standard package; otherwise it is not.

This section also introduces some simple calculations using Float and Natural (nonnegative integer) quantities. It is important to emphasize that Ada does not allow float and integer quantities to be directly combined in an expression. Forced or explicit conversion between integers and floats is permitted, but taken up in detail in Chapter 8, and is best postponed until that time.

This is a good time to emphasize the idea of using subtypes such as Natural and Positive. A subtype variables with ranges appropriate to the calculation being done. As a first step, explain that Ada will raise an exception if a negative number is stored in a Positive or Natural variable, and that this is a good thing because it prevents meaningless calculations from being done. Point out to the students that they will be expected to define their own subtypes to specify the meaningful range of values of their variables.

I've found that subtypes come quitre naturally to students with no programming experience, and of course those with prior Pascal experience will have used subtypes (called subranges in Pascal) before. Students with C experience will not have seen range constraints subtypes before and might need help in understanding why such things are useful.

Section 3.3

Be sure that students understand that constants are used to give names either to mathematical values like Pi or physical conversion factors, or program constants like the maximum number of data points allowable in a calculation. The advantage of using a constant is that its value cannot be changed accidentally by an assignment statement.

Explain that comments are to be used to explicate and document program statements, not to repeat them. Also explain that comments, blank lines, and spaces used for indentation are ignored by the compiler but are required out of concern for the reader of the program, and to make the program look aesthetically professional.

Section 3.4

This is a good opportunity to point out the error in using a semicolon instead of IS in a program heading. This mistake is often made by students with Pascal experience. Because a statement such as

PROCEDURE Hello;

is valid, but not in this context, some compilers will accept it and proceed. This may give rise to multiple propagation errors because the parser treats nearly every successive statement as "out of context." You might illustrate this with a compiler listing from the class compiler. It is a good chance to discuss propagation errors and the fallibility of parsers, and advise the students not to panic when a simple program produces twenty diagnostics. They should correct the first error and try again; often the rest of the messages will disappear.

GNAT (the GNU Ada 95 compiler) is especially clever in diagnosing, and recovering from, errors of this kind. One of its heuristics uses the program statements' indentation to try to guess the programmer's intent. This is very unusual. If you are using GNAT, you might mention it to your students as yet another reason to indent their code consistently, right from the start. Students who write everything flush-left, like an old BASIC program (they always promise to clean it up before turning it in) are cheating themselves out of not just a better understanding of their own code, but also of GNAT's error recovery help!

Section 3.5

This section introduces the first major Case Study. In my course, I require the students to develop their own programs systematically according to the Case Study form. If they complain that this development documentation is overkill for tiny programs, explain that good habits are developed little by little, and that the discipline they acquire will pay off when the programs get more complex. Be careful that your documentation requirements really aren't overkill; make sure the expected size of the documents scales up with the size of the program.

The Software Development Method is a scaled-down version of the traditional industry development process and learning it is a student's first step toward professionalism. In my course, project submission and grading is broken down as follows:

  • 30% general case study documents except for the test plan
  • 20% test plan
  • 20% general internal code style (comments, white space, variable names, case consistency, etc.)
  • 30% the program "gets the right answer"
I emphasize the test plan because students must learn to think about how they will test a program, before they write the code. In class, I explain that I require students to predict the behavior of their programs, even in cases of "bad" input. For example, if a given quantity cannot meaningfully be negative, they must say what their program will do if a negative quantity is entered by a user, and they must test accordingly.

At this early stage, of course, students cannot yet write programs that "stay alive" even if the input is poorly formed or out of range. They cannot learn everything at once. This does not prevent us from requiring that they predict, honestly, that a program will (for example) terminate on Constraint_Error if out of range input is entered, and that they provide a negative test value to demonstrate that their prediction was correct. The goal is to cause them to think about it, and to follow a "truth-in-advertising" principle. In my experience, fostering this attitude is well worth doing; students are genuinely proud of writing programs whose behavior they really understand.

The requirement for a full-blown Case Study often comes as a rude awakening to students with experience in other programming courses, especially in high school where the goal was just to pound out the code. To students who complain, I explain that my course is the foundation course for a professional career, and this is what professionals do in their daily work. Students who go on into summer or co-op employment in industry often tell me how much the Case Study approach really prepared them for their jobs, and how impressed their supervisors were that they actually learned about this in their first university course!

Section 3.6

There are students to whom the meaning of an assignment statement is less than obvious. First, some students confuse an assignment with an algebraic assertion of equality and are thus baffled by statements of the form X := X + 1. Interestingly, there are others who, having learned a spreadsheet system, think that the left side of an assignment is automatically updated when the right side changes. Suppose we have
B := 2;
A := B + 1;
B := 3;
Ada.Integer_Text_IO.Put(Item => A);
A student who thinks that the output is 4 has fallen into this trap. Students must learn that in procedural languages, statements are executed sequentially.

Emphasize that reading a value into a memory location, or storing one with an assignment, destroys the previous value, but that examining the contents of a location leaves it unchanged.

Section 3.7

Remind students that, when numeric data is displayed using formatting parameters, the field width is automatically increased to display a number that will not fit in the specified field. This is used to advantage in the book examples, where a width of 1 is often used to embed an output value in a message, where extra spaces would produce an ugly document.

Ada's I/O is cumbersome compared with Pascal's or C's, because each predefined Put displays only a single token and each Get reads only a single token. The advantage of it is that I/O procedures follow the same parameter-matching rules as do ordinary procedures. It does take getting used to, especially for students with experience in languages that have specialized I/O statements that allow multiple parameters. On the other hand, because the I/O packages are just packages providing ordinary procedures, knowledge about them is reusable in other package and procedure contexts.

It is often helpful for students to write a short program that displays the same value with many different combinations of formatting parameters, especially in the floating-point case. The language default is to display a Float value in E-notation; the exponent is suppressed by supplying Exp => 0 to the Put.

The section does not concentrate on reading strings. If you choose to emphasize this more, keep in mind that Ada requires that string lengths match exactly. In the case of input, this means that Get will attempt to read exactly the number of characters called for by the string length, and will ignore RETURN keypresses. A student may think the program is "hung" when it is merely waiting for more characters. A comprehensive and systematic discussion of strings and string I/O is provided in Chapter 10.

Section 3.8

Emphasize the primary reason for having types: to represent real-world objects. Integer variables are used for counting things; Float variables are used for computations needing fractional parts, and therefore should not be used for counting. Students with Pascal or C experience will understand this, but not the fact that Ada prohibits direct mixing of integer and float values. Reiterate that if X is an Integer variable, X := 2/3; will store 0 in X, and that if X is a Float variable, the assignment must be written X := 2.0/3.0;.

The introduction of one user-defined subtype, NonNegFloat, provides an opportunity for discussion about the appropriate ranges of variables, and for the fact that Ada lets programmers define their own ranges, a facility provided by Pascal but not by Fortran or C.

Too much is often made of operator precedence and association rules. We prefer to see these as defaults, used by the compiler when parentheses are omitted. Students should be encouraged to use parentheses liberally, at least until they have a thorough understanding of precedence. Precedence is taken up in detail in Chapter 8, but even there the emphasis is on using parentheses instead of trying to memorize a complicated table of precedences.

Section 3.9

Discuss the output from your class compiler, showing examples if possible. Explain the difference between compilation errors and execution errors, including the reasons why a compiler cannot always detect an error, e.g., a computed result that goes out of range. In discussing exceptions, mention that in Ada programs can trap exceptions and act to correct the execution errors instead of just "crashing," and that exception handling will be covered beginning in Chapter 6.