Defining Functions by Cases


Breaking problems down into cases

Suppose that you want to find out which of two numbers x and y is the larger of the two. That problem naturally divides into two cases.

  1. In the case where xy, the answer is clearly y

  2. In the case where y < x, the answer is clearly x

We will see that a large number of computational problems can be dealt with by breaking them down into cases and solving each case separately. Then, it is just a matter of making a decision about which case we are presented with in a given instance of the problem. That is, the program must make a decision.


Function definitions with more than one case

A simple way to make a decision in a definition of a function is to write more than one equation, but to write, after each equation, the condition under which we claim that it is true. Suppose that max(x,y) is suppose to yield the larger of x and y. As we have seen above, there are two cases. Expressed as equations, they are

   max(x,y) = y     when x ≤ y
   max(x,y) = x     when y < x
Cinnameg allows you to write multiple equations like this, provided you write the word case in front of each equation. Also, be sure to change ≤ to <=. So in Cinnameg, you write
   case max(x,y) = y     when x <= y
   case max(x,y) = x     when y < x
The word when is followed by an expression that produces a boolean answer. To do a computation, you start with the first equation, and check whether its condition is true. If so, you use the first equation. If not, you move on to the next one. You keep going until you hit an equation whose condition is true, and you use that one.

You typically omit the condition (and the word when) from the last case, indicating that it will always be used if none of the previous equations had a true condition. So another definition of the max function is

   case max(x,y) = y     when x <= y
   case max(x,y) = x 


Hand simulations

It is important to try your definitions. Let's try computing max(3+1, 2*9).

  max(3+1, 2*9)
    = max(4, 2*9)
    = max(4, 18)
    = 18          (by the first equation for max, since 4 <= 18 is true)
But to compute max(3+4, 2+1), the computation is as follows.
  max(3+4, 2+1)
    = max(7, 2+1)
    = max(7, 3)
    = 7          (by the second equation for max, since 7 <= 4 is false)


Case study: Absolute value of a number

Cinnameg provides you with function abs(x), which yields the absolute value of x. But if it were not already available, you could create it yourself. Choosing a different name, let's define absolute(x) to produce the absolute value of x. For example, absolute(8) = 8 and absolute(-8) = 8. There are two obvious cases.

  case absolute(x) = x     when x >= 0
  case absolute(x) = -x


Case study: Finding the largest of three numbers

Now suppose that you want a function that takes three numbers and produces the largest of the three. Let's call it largest(x,y,z). The answer is either x or y or z. So there are three obvious cases.

  case largest(x, y, z) = x    when x >= y and x >= z
  case largest(x, y, z) = y    when y >= x and y >= z
  case largest(x, y, z) = z

Would the following definition work instead?

  case largest(x, y, z) = x    when x > y and x > z
  case largest(x, y, z) = y    when y > x and y > z
  case largest(x, y, z) = z
Think about computing largest(5,5,3). That is, x = 5, y = 5 and z = 3. Since x > y is false, the first case is not chosen. Since y > x is also false, the second case is not chosen. So the third case is taken, and the answer is 3. That is obviously incorrect.

It is important for a function to work correctly no matter what its arguments are. In practice, people find that it is somewhat unusual arguments where their functions give the wrong answer. So, when testing function definitions, think about unusual arguments. In the case of largest(x,y,z), an unusual situtation is where two of the arguments are the same.


Context issues

Recall that each function is a separate context. The names that it uses for its arguments do not have anything to do with names used in other contexts.

When you use more than one case, each case is also a separate context. One case cannot use names defined in a different case. They are completely separate.


Problems

  1. [solve] Write a definition of function min(x,y), which produces the smaller of x and y.

  2. [solve] The median of three numbers is the one that is in between the other two. More precisely, y is the median of x, y and z if xyz. Write a definition of function median(x,y,z), which yields the median of x, y and z.

  3. [solve] Does your definition of the median function from the preceding question work correctly to compute median(2,2,3)? Check it carefully. (The correct answer is 2.) If it does not work, how can you fix it?

  4. [solve] You can also compute the median of three numbers x, y and z as x + y + z - a - b where a is the smallest of x, y and z and b is the largest of x, y and z. Suppose that you have already defined functions smallest(x,y,z) and largest(x,y,z). Give a single-equation definition of median(x,y,z).

    (For this problem, definitions of smallest(x, y, z) and largest(x, y, z) are provided.)

  5. [solve] Another way to get the largest of three numbers x, y and z is to compute the larger of x and y, and then to compute the larger of that number and z. Write a definition of largest(x,y,z) that only uses one defining equation, but that uses function max to find the larger of two given numbers.

    For this problem, function max(x, y) is available to you.


Summary

A common way to solve problems is to break them down into cases, where you have a different way to solve each case. You can do that by deciding among equations to use.

Test a function definition using a hand simulation on simple arguments. Do not just assume that the function is right.


Review

Ask a questions using an expression whose value is true or false. Often, you use comparisons such as < and > to ask questions. You can also formulate larger questions using and and or.

You can expect to make mistakes. Try to keep your definitions simple and elegant. That way they are more likely to work.

Decide on your algorithm. If you get errors, never let the compiler bully you away from your algorithm. You must be the boss. Think about the right way to fix an error. If you cannot see how to fix an error without being pushed away from what you really want to do, ask for help.


Review questions

  1. [solve] Not all functions require more than one case.

    The distance between two numbers x and y on the number ine is |x - y|. Write a definition of function absdiff(x, y). (Recall that abs(v) is the absolute value of v.)