This is an archived version of the course. Please find the latest version of the course on the main webpage.

Chapter 8: Composition and abstraction

Composition in functions

face Josiah Wang

Composition also happens with functions.

You can use the composite expression from earlier directly as function arguments:

sin_x = math.sin(x_in_degrees / 360.0 * (2 * math.pi))

Using composite expressions as function arguments

Of course, you might choose to just name the composite expression and pass in the variable instead as the argument. This produces yet another abstraction ‘hierarchy’. At this level, you do not even need to worry about how x_in_radians is formed.

sin_x = math.sin(x_in_radians)

Using variables as function arguments

You can also compose function calls and chain them, just like mathematical functions e.g. f(g(x)).

y = math.exp(math.log(x+1))
Composing functions

print(type(int(math.exp(3.5))))

Composing functions

Remember, each function returns an object. This object can in turn be passed on as the input argument to another function.

If you think about programs this way, you may notice that what you are actually doing is to break down a problem into smaller subproblems.

You can then solve the smaller subproblems first (without worrying about the bigger problem). For example, you can solve converting an angle in degrees to radians first.

Once you have solved the smaller subproblems, you can then compose the different solutions together to address the larger problem. For example, you can now compute the sine of an angle in radians.

Breaking the problem down into small pieces like this will make it easier for you to solve programming problems. This will stop you from being overwhelmed with all the details at any given time, especially as you write more complex programs. You can now think of a programming problem as a composition of simpler problems, and solve each simpler problem individually.