On this page:
1 The function name
2 The signature
3 The purpose statement
4 The examples and tests
5 A complete function definition
6 Practice

Lab 2: Defining functions

You may submit this lab to lab2 on Handin (this is optional).

In this lab, we will learn the basics of how to define a function. We will also learn some of the required coding conventions for COMP 115.

1 The function name

The first step in defining a function is to come up with a name. It should be suggestive of what it does (like "substring" or "overlay") and relatively brief.

Convention: In COMP 115, function names will always be entirely lowercase. If the function name involves more than one word, the words must be separated by hyphens (like "string-append"). This is called kebab case.

2 The signature

The next step in defining a function is to determine what types of data are being used as inputs and what type of data the function produces, and to write this information next to the name of the function in what is called a signature.

At this point, we know about the following types of data: Number, String, Image, and Boolean.

Convention Input types are capitalized. (We will later see that they are written in upper camel case.)

For example, the substring function takes three pieces of data, a string and two numbers, and produces a string. Here is the signature for substring:

; substring : String Number Number -> String

Note that the signature is a comment; that the name of the function is separated from the types by a colon; and that the input types are separated from the output types by an arrow "->".

Exercise 1: Write down the signature for sqr.

Exercise 2: Assume that the function + takes exactly two arguments. Write down the signature for +.

Exercise 3: Assume that the function string-append takes exactly two arguments. Write down the signature for string-append.

Exercise 4: Write down the signature for not.

Exercise 5: Assume that the function or takes exactly two arguments. Write down the signature for or.

Exercise 6: Write down the signature for the function =.

Exercise 7: Assume that the function < takes exactly two arguments. Write down the signature for <.

Exercise 8: Assume that the function overlay takes exactly two arguments. Write down the signature for overlay.

Exercise 9: Write down the signature for place-image.

Exercise 10: Write down the signature for rectangle.

3 The purpose statement

The next step in defining a function is to write down a concise description of what the function does. Do not repeat information that is already in the signature: for example, there’s no need to say that substring "takes a String, Number, and a Number and returns a String" because the signature already says as much.

; substring : String Number Number -> String
; trims the input string to the given starting and ending positions

Exercise 11: Write down a purpose statement for sqr.

Exercise 12: Assume that the function string-append takes exactly two arguments. Write down a purpose statement for string-append.

Exercise 13: Assume that the function or takes exactly two arguments. Write down a purpose statement for or.

Exercise 14: Assume that the function < takes exactly two arguments. Write down a purpose statement for <.

Exercise 15: Assume that the function overlay takes exactly two arguments. Write down a purpose statement for overlay.

Exercise 16: Write down a purpose statement for rectangle.

4 The examples and tests

The next step in defining a function is to generate some concrete examples of how it is supposed to behave. Here are some examples for substring:

; substring : String Number Number -> String
; trims the input string to the given starting and ending positions
; Given: "COMP 115" 0 4               Expect: "COMP"
; Given: "15 September, 2021" 3 12    Expect: "September"

Exercise 17: Write down three different examples for sqr.

Exercise 18: Write down two different examples for <.

Writing down examples in this manner, we are leaving it to the human reader to check whether or not the function being defined actually behaves as expected. As it turns out, DrRacket can check this for us. This is called automated testing. Each example can be used as a unit test.

A BSL feature that allows us to automate these examples is called check-expect. Here are two tests for substring:

; substring : String Number Number -> String
; trims the input string to the given starting and ending positions
(check-expect (substring "15 September, 2021" 3 12) "September")
(check-expect (substring "COMP 115" 0 4) "COMP")

Exercise 19: Turn your examples for sqr into tests using check-expect.

Exercise 20: Turn your examples for < into tests using check-expect.

5 A complete function definition

A complete function definition includes a signature, purpose statement and tests. When we cover the design recipe, we will discover that there is more to consider. But for now, it is enough to know that all of these ingredients are essential.

Here is a complete function definition from this week’s lecture:

; grid : Image -> Image
; arranges 4 copies of the input image into a square formation
(define (grid img)
  (above (beside img img)
         (beside img img)))
 
(check-expect (grid (square 20 "outline" "cyan"))
              (above (beside (square 20 "outline" "cyan")
                             (square 20 "outline" "cyan"))
                     (beside (square 20 "outline" "cyan")
                             (square 20 "outline" "cyan"))))
(check-expect (grid (triangle 20 "solid" "orange"))
              (above (beside (triangle 20 "solid" "orange")
                             (triangle 20 "solid" "orange"))
                     (beside (triangle 20 "solid" "orange")
                             (triangle 20 "solid" "orange"))))
6 Practice

Exercise 21: Define a function celsius->fahrenheit which converts a temperature given in Celsius to a temperature in Fahrenheit.

Exercise 22: Define a function first-three-letters which takes a String and returns its first three letters. Use substring.

Exercise 23: Define a function dist-from-origin which takes two numbers, the x-coordinate and the y-coordinate of a point, and returns the distance of that point from the origin.