5B. What Are Functions Good For?

Functions are critical for breaking a large program up into manageable pieces. But there are some other reasons for writing functions.


Avoiding code duplication

The more code you write, the more opportunities you have for making mistakes, and the more opportunities you have, the more mistakes you will make. Clearly, you want to avoid writing the same code more than once.

But what if you have two bits of code that are similar but not identical? For example, in one place you need

  d = sqrt(pow(x1-x2, 2) + pow(y1-y2, 2));
but in another place you need
  r = sqrt(pow(a-c, 2) + pow(b-d, 2));
You can avoid this duplication by creating a function.
  // distance(x1,y1,x2,y2) returns the distance between
  // points (x1,y1) and (x2,y2) in the plane.

  double distance(double x1, double y1, double x2, double y2)
  {
    return sqrt(pow(x1-x2, 2) + pow(y1-y2, 2));
  }
then replace the two statements by
  d = distance(x1,x2,y1,y2);
and
  r = distance(a,b,c,d);
Not only does that avoid duplicating code, but it makes what you are doing more clear. It also allows you to make improvements that would be awkward when the code is duplicated. It is much more efficient to compute z*z than to compute pow(z,2). So you write function distance as follows, as we did earlier.
  // distance(x1,y1,x2,y2) returns the distance between
  // points (x1,y1) and (x2,y2) in the plane.

  double distance(double x1, double y1, double x2, double y2)
  {
    double deltaX = x1 - x2;
    double deltaY = y1 - y2;
    return sqrt(deltaX*deltax + deltaY*deltaY);
  }

I expect you not to duplicate code unnecessarily, and you will lose points for duplicating code. But don't overdo it. If an expression or statement is short and simple, just write it. For example,

  n++;
can occur in several places. Don't try to make a function that adds 1 to a variable. Use a function when doing that makes the program simpler or more readable.


Shortening function definitions

If you underutilize functions, you will find that the bodies of the functions that you write are very long. Long function definitions are difficult to understand and difficult to get to work.

Put code that has a coherent purpose into a function definition, so that you don't need to clutter another function definition with details that are better put aside. A function whose body does two steps might look something like this.

  void doSomething(int x)
  {
    int y = firstStep(x);
    secondStep(y);
  }

Details of the two steps have been set aside into two functions. (But choose more descriptive names than firstStep, etc.)

There is a close relationship between reducing the sizes of function bodies and top-down design. Don't wait until the body of a function becomes unwieldy. While you are writing a function definition, think about other functions that you would like to make use of. If they don't already exist, put them aside (with documentation on what they are intended to do) and write the deferred function definitions later.


Encapsulating decisions and algorithms

A function is an expert on some small thing. For example, a function that computes square roots is an expert on how to compute square roots. No other part of the program needs to be concerned with that; if you want to compute a square root, ask the expert to do that for you.

A programmer needs to make decisions when writing software, such as how to represent a particular piece of information or type of information. Functions can also be experts on those decisions, since, in order to do use information, a function needs to know how that information is represented. Any function that makes direct use of the decision is one of the experts on that.

If one function wants to make use of some information, it asks one of the experts on information to do the job.

A given decision might need to be known by more than one function, but as a software designer, you try to minimize the number of functions that need to know the result of a decision. That way, if you change the decision (and you will change decisions), you have only a small number of functions to modify. We will see more on that later when we look at abstract data types.


Summary

Using functions can reduce code duplication and allow you to write only short function definitions.

Keep ease of modification in mind while writing software. One way to ease modification is to keep decisions localized in one or a small collection of functions.