# C++ Notes: Function Concepts

## Purpose of functions

The purpose of functions is to make the programmer's life easier.

- Write code once, and call it from many places. This insures consistency, and reduces the cost of writing and debugging.
- A function allows code to be parameterized by passing values to it.
- Functions can be collected in libraries and reused in other programs.
- Functions create new conceptual units that form the units that programmers use in thinking about a problem.

## Naming

For a function to work well as a conceptual unit it has to have a name that is clear to the human reader.

- Choose a name that has a clear meaning. Eg, "f" is not a good name.
- Void functions are more readable if a verb name is used that describes what it does. Eg, "printAverage" would be a good name for a void function that prints the average of some numbers. "Average" would not be a good name for it.
- Value-returning functions
  - A verb is a good choice for a value returning function that performs an operation that would naturally be understood to produce a value, eg, "add(x, y)". A noun which describes the the result can be used. For example, "remainder(a, b)" would be a good choice for a function that computes the remainder after division (ie, what the "%" operator does). The noun is a good choice if you're tempted to add a word like "compute" or "calculate" in front (eg, "computeRemainder(a, b)"). The "compute" or "calculate" is simple often omitted if the meaning is clear.
  - Getter and setter functions. Prefix functions which get a value from an object or data structure with "get" (eg, `getTime()`). Similarly use "set" for functions that set values (eg, `setTime()`).
  - boolean functions should usually start with "is" or another word that suggests a yes/no answer. Eg, "isOdd(n)" is a good name for a function that returns true if its parameter is odd, and it's better than simply "odd()".
- Case. There are several conventions, but whichever one you choose, be consistent to make programs readable. The most common convention is to start names with lowercase and capitalize the first letter of each additional word in the name. Some programmers start functions with uppercase characters, but this is less common.

## Cohesion

Each function should do only one thing. This should be done so that the conceptual unit can be understood easily. Sometimes it will be convenient to do two things in a function because you're working on the same data. Try to resist this temptation. Make two functions if you reasonably can.

Separate I/O and computation. Greater cohesion is almost always achieved by separating I/O and computation. If possible, put the I/O in main or in separate functions. If I/O is properly separated, the same functions which make up a program can be used either in a GUI or command-line program.

## Side-effects

Functions should avoid side-effects such as communicating by means of global variables. Use of global variables increases coupling, which makes programs harder to debug and maintain.

## Functional Decomposition - top-down programming - successive refinement

The top-down programming style is to write a short main program that calls on additional functions to accomplish it task. These functions should similarly be kept short and call more functions if necessary to get their task done. Start with the main function, and write only function stubs which do almost nothing except maybe print a message that they were called. Get this running, then expand one of the stubs, get this running, ... . This very productive style of programming is related to iterative programming and is one of the cornerstones of Extreme Programming.

Top-down programming is good for for small programming tasks. A better approach for larger programs is to divide them into objects.

## Size - One page

It is a good idea to keep functions shorter than one page or one screen. This makes them easy to comprehend, If you want to make them larger, think about how you could break the processing into two or more functions (top-down programming).

## Parameters

- Value parameters copy the actual parameter value into the formal parameter. Changes to the formal parameter, which is a local variable, do not get passed back to the calling program.
- Reference parameters are implemented by passing the memory address of the actual parameter to the formal parameter. Reference parameters are used to pass values back from a function. This is necessary to return more than one value.
- It is helpful to have a clear idea of the direction of data flow of each parameter: in means the data only flows into the function (typically a value parameter), out means the data only flows out of the function (a reference parameter), or inout means that data flows both into and out of the function thru this (reference) parameter. There is no language support for these ideas in C++ altho these keywords are used in the Ada programming language.

## Prototypes

The compiler must know about the return and parameter types before it can understand the call to a function. You should declare all of your function prototypes at the beginning of your program. This is one of the primary purposes of the system include files. If you've written a number of functions in many files, it is common to define your one include file which defines the prototypes.