Composition

One of the motivations for having weekly homework in this class is that learning to program is a lot like learning a new language, so daily practice is really helpful if you can manage it.

When learning a new language, you start by developing your vocabulary: el gato, mesa, sobre . Then you start figuring out how to put words together to form sentences: el gato está sobre la mesa. And then, you begin to focus on writing completely paragraphs (which I’ll skip because I’m didn’t that far in Spanish — muy triste!). So the progression moves from words level, to sentence level, to paragraph level. And as you progress, you build a more complicated structure out of simpler building blocks.

The idea of “building” more complex ideas out of simpler one’s is essential in both programming and mathematics. Today, we’re going to focus on how to build function out of simpler functions. To begin, let’s revisit an example from HW#1, and let’s write the following two functions:

def percentage_grade(score: float, total:float) -> float:
	return score/total 

def stringify(percent: float) -> str:
	return "You got " + str(percent) + " of the questions correct"

What do you notice about these two functions?

Screenshot 2024-09-29 at 9.57.35 AM.png

We’ll the first one takes two floats and returns a float. The second one takes a float as an input and returns a string. So presumably, we could call stringify after percentage_grade as follows.

score = 112.0 
total = 156.0 
percent = percentage_grade(score, total)
stringify(percent)

By calling the function stringify on the output of percentage_grade we’ve in a sense created a new function. This new function takes two floats as arguments and returns a string.

Calling two functions in order, where the output of the first function is used as the input to the second function is known as composing functions. We can denote this process mathematically via the $\circ$ operator between the two functions as in $\text{stringify} \circ \text{percentage\_grade}$. In Python, we can write this as a single function as follows:

def f(score:float, total:float) -> str:
	percent = percentage_grade(score, total)
	s = stringify(percent)
	return s 

Screenshot 2024-09-29 at 9.59.45 AM.png


<aside>

Check Your Understanding

Write a function which is the composition of the following two functions:

def f(x):
  if x % 2 == 0:
    return 1
  else:
    return -1
    
def roll(key):
  return jax.random.choice(key, sample_space)

</aside>