How to Design Programs: An Introduction to Computing and Programming
Designing Functions that Change Structures
gradually introduced the idea of mutable structures. In the first of the two sections we studied the idea
of changing a
ly defined variable through a function. In the second one, we discussed how structures could be
Now we need to learn when and how to use this new power. The first subsection concerns the question of why a
program should modify a structure. The second reviews how the existing design recipes apply when we wish to use
mutators. The third one discusses some difficult cases. The last one is dedicated to the differences between
Why Mutate Structures
Whenever we apply a structure constructor, we create a new structure. On some occasions, this is truly what we want.
Consider a function that consumes a list of personnel records and produces a list of phone book entries. The personnel
records may contain information about a person's address, including the phone number, date of birth, marital status,
closest relatives, and salary level. The entry for the phone book should contain the name and the phone number and
nothing else. This kind of program should definitely generate a new structure from each structure in the given list.
On other occasions, though, creating a new structure doesn't correspond to our intuition. Suppose we wish to give someone
a raise. The only way of accomplishing this at the moment is to create a new personnel record that contains all the
old information and the new salary information. Or, suppose someone has moved and received a new phone number, and
we wish to update the phone book on our PDA. Just like the program that changes a person's salary level, the program
that updates the phone book would create a new phone book entry. In reality, however, we would not create a new
personnel record or a new entry in the phone book. We would instead correct the existing personnel record and the
existing entry in our phone book. A program should be able to perform the same kind of corrective action and, with
mutators, we can indeed develop such programs.
Roughly speaking, the examples suggest two cases. First, if a structure corresponds to a physical object and the
computation corresponds to a corrective action, the program may mutate the structure. Second, if a structure does
not correspond to a physical object or if the computation creates a new kind of value from existing information, the
program should create a new structure. These two rules are not clear-cut. We will often encounter situations where
both solutions are feasible. In that case, we must consider an ease-of-programming argument. If one of the two solutions
is easier to design -- often the creation of a new structure, choose it. If the decision leads to a performance bottleneck --
and only then, restructure it.