Inlab: Design Recipe

Keep in mind that the design recipe we will be applying to just about ALL future functions we write consists of four parts:

  1. The type signature (aka "contract"), which tells us how many and what types of inputs a function takes, and what type of data it returns. Note that the types we currently know about include Numbers (Integers & Fractions), Strings, Symbols, Booleans, and Images. E.g., draw-clock :: Number Number Number -> Image.
  2. The purpose statement, which is a short description of what the function does. E.g., "draws a colored, digital clock face given the time in hours, minutes, and seconds."
  3. Examples that demonstrate how the function should work on specified inputs. Examples are best written using one of the check- functions (e.g., check-expect, check-within, check-range) so that DrRacket can automatically test them for us. A test for draw-clock might look liks this:

    (check-expect (draw-clock 9 5 18) 
                  (beside (text "9"  20 'red) 
                          (text ":"  20 'black)
                          (text "05" 20 'blue)
                          (text ":"  20 'black)
                          (text "18" 20 'green)))
    
  4. A template for our function. For now, a function template will simply tell us the name of the function and the local variables that will hold its inputs. The body of the function will start out as an arbitrary value that has the same type as its expected output. E.g., the following is a template for draw-clock:

    (define (draw-clock hours minutes seconds)
      (empty-scene 100 100))
    

    A simpler function, such as k2f (a conversion function from Kelvin to Fahrenheit), may appear simply as:

    (define (k2f k)
      0)
    

Here's the completed design recipe for draw-clock:

; draw-clock :: Number Number Number -> Image
; draws a colored, digital clock face given the time in hours, minutes, and seconds
(check-expect (draw-clock 9 30 18) 
              (beside (text "9"  20 'red) 
                      (text ":"  20 'black)
                      (text "30" 20 'blue)
                      (text ":"  20 'black)
                      (text "18" 20 'green)))
(define (draw-clock hours minutes seconds)
  (empty-scene 100 100))

Recap: Signature, Purpose, Examples, Template. Recite until memorized. Remember: for each function you need to implement, you will be writing down these things BEFORE you start work on its body. For every program that consists of more than one function, it is also likely that you will be writing out the design recipes for all of the functions BEFORE any single function is completely implemented!

Of course, actually implementing the function body itself is also part of the design process, but we will now be saving that for last.

Practice Exercises

Let's practice designing a number of functions. For each function, come up with at least 3 different tests. Take it slow -- the goal here is to apply the design recipe, not at all to jump into the implementation!

We'll start with some you've seen before:

And next:

For these next two, you'll need to use check-within instead of check-expect, because you'll be dealing with inexact numbers: