Lab: Getting Started with Scheme

Monday, Sep 3, 2018
Lab writeups are due at 10:30pm on the day of the next class meeting. For example, a Wednesday lab is due at 10:30pm on Friday. Each lab writeup will be announced at the end of class on a lab day.
In this laboratory, you will begin to type Scheme/Racket expressions, using DrRacket. Scheme is the language in which we will express many of our algorithms this semester. Racket is a particular implementation of Scheme (which varies a bit from the Scheme standard). DrRacket is the environment in which we will write those programs.


Many of the fundamental ideas of computer science are best learned by reading, writing, and executing small computer programs that illustrate those ideas. One of our most important tools for this course, therefore, is a program-development environment, a computer program designed specifically to make it easier to read, write, and execute other computer programs. In this class, we will often use a program development environment named DrRacket along with the programming langauge Racket, a dialect of a language called Scheme, which is itself a dialect of a language called LISP. Although Racket is a dialect of Scheme, we will often refer to it as “Scheme”.

In this lab, we explore the Scheme language and the DrRacket program development environment.


Start by comparing your answers on the self-check from the reading on DrRacket with your partner’s answers. After you’ve done the comparison and discussed any differences in your responses, you are ready to begin the computer work.

While we set up DrRacket to use the code for this course in the previous lab, it is also useful to setup a place for DrRacket to load the code you will write during this semester. You can specify multiple places for DrRacket to search, but we will start with your desktop on MathLAN workstations.

To do this, we will first need to open a Terminal window. Look for an icon of a computer monitor near the lower-left corner of the screen with a dollar sign and an underscore. If you see this icon, move the pointer over the icon and click the left mouse button once to launch the Terminal.

If you do not see a Terminal icon, then move the pointer onto the Applications menu icon at the bottom left of the panel (in Xfce, it looks like a creature on a blue X) and click once with the left mouse button. The applications menu will pop up. Move the mouse over System, then Xfce Terminal Click the left mouse button once to launch the Terminal.

In the terminal window, you will see a shell prompt. The default shell prompt shows looks something like this: student@shaw:~$. This prompt tells us the current acccount (student), the name of this machine (shaw), and the current directory (~, which is shorthand for your home directory). This prompt indicates that the shell is ready to receive instructions.

You type in such instructions using the keyboard. Move the mouse pointer into the Terminal window and click the left mouse button to make the window active. Notice that the window frame changes color following the click, indicating that the window has become active.

We will instruct DrRacket to look for code on your desktop with the following command. For this course, terminal commands will be displayed with white text on a black background, despite the fact that Xfce uses black-on-white as a default theme. This should distinguish terminal inputs from code that should be entered into DrRacket. When you enter these commands, do not include the shell prompt.

$ raco link ~/Desktop

Press Enter. You will know the incantation worked when a new shell prompt appears.

You can now close the terminal window. To do this, press Ctrl+D. That is, hold down either of the keys marked Ctrl, and simultaneously press the D key. (On our workstations’ keyboards, the keys marked Ctrl (“control”) and Alt (“alt” or “meta”) are somewhat like Shift keys, in the sense that they modify the effect of other keys that are pressed simultaneously.) The shell program interprets Ctrl + D as a signal that you have no more instructions for it and halts, and the terminal emulator closes the window automatically once the shell stops running. Alternatively, you may close a window by moving the mouse to the x at the top-right of the window, and clicking the left mouse button. Finally, you can usually type exit to close a terminal window.

Note: The partner who did not log in will need to type this incancation in the future before using DrRacket. Fortunately, you only have to do it once for the semester.

If you successfully completed the Linux laboratory, you should have an icon for DrRacket at the bottom of your screen. Click on that icon to start DrRacket.

You will also need to configure DrRacket to behave properly. (If all goes well, you will only need to do this once.)

In the Language menu, select Choose Language…. A dialog box will appear. Click the radio button next to “The Racket Language”. Then click OK. The dialog should disappear.

Click the Run button to make sure the changes take effect. You should see “Language: racket”, or something similar, in the bottom pane.


Exercise 1: Discovering DrRacket’s interactions pane

Short Version

  • The lower text area is called the interactions pane.
  • You type Scheme commands there and DrRacket responds.
  • Type the first few examples from the reading.
    • (sqrt 144)
    • (+ 3 4)
    • (+ 3 (* 4 5))
    • (* (+ 3 4) 5)
    • (string-append "Hello" " " "Charlie")
  • The self-check in the reading asked you to predict some values. Determine whether your prediction matches what DrRacket computes.
> (square 4)
> (* (+ 4 2) 2)
> (- 1 (/ 1 2))
> (/ (- (+ 2 3) 1) 2)
> (expt 2 3)

Detailed Version

As you may remember from the reading on DrRacket, the DrRacket window has two panes, one for definitions and one for interactions. Just as in the reading, we’ll begin by considering the interactions pane.

The best way to understand the interactions pane is to use it. So, let’s try the first few examples from the reading. Type each in the pane, hit return, and see if you get the same value.

> (sqrt 144)
> (+ 3 4)
> (+ 3 (* 4 5))
> (* (+ 3 4) 5)
> (string-append "Hello" " " "Charlie")
"Hello Charlie"

Of course, one should not just thoughtlessly type expressions and see what value they get. Particularly as you learn Scheme, it is worthwhile to think a bit about the expressions and the values you expect. The self-check in the reading asked you to predict some values. Determine whether your prediction matches what DrRacket computes.

> (* (+ 4 2) 2)
> (- 1 (/ 1 2))
> (/ (- (+ 2 3) 1) 2)
> (expt 2 3)
> (square 4)

If you get an unexpected error message in one or more cases, that may be part of the intent of this exercise. Go on to the next exercise and, if you still get error messages, talk to your instructor or a class mentor.

Exercise 2: Libraries

As you may have noted, you get an error when you try to square the number 4.

> (square 4)
square: undefined;
 cannot reference undefined identifier

Why do you get an error? Because the square procedure is not built in to standard Racket. You will soon learn how to define your own version of square. Until then, you can tell DrRacket to use ours. At the top of the definitions pane (but after #lang racket), add a line that reads

(require csc151/square)

Click the Run button and try squaring 4 again. If you get an error message, make sure that you followed the instructions for configuring DrRacket with the csc151 package during the Linux lab. If you still get errors, ask for help.

Exercise 3: Reflection: How do you know a result is correct?

Short Version

  • Try typing (sqrt 137641).
  • Reflect on how you know whether or not the answer is correct.

Detailed Version

Of course, the computer is using some algorithm to compute values for the expressions you enter. How do you know that the algorithm is correct? One reason that you might expect it to be correct is that Scheme is a widely-used programming language (and one that we’ve asked you to use). However, there are bugs even in widely-used programs. You may recall a controversy a few years back in which it was discovered that a common computer chip computed a few specific values incorrectly, and no one had noticed. More recently, it was found that the output routine in Microsoft Excel produced the wrong output for a few values. And you may have some evidence that your faculty like to trick you. Hence, you might be a bit suspicious.

Each time you do a computation, particularly a computation for which you have designed the algorithm, you should consider how you might verify the result. (You need not verify every result, but you should have an idea of how you might do so.) When writing an algorithm, you can then also use the verification process to see if your algorithm is right.

Let’s start with a relatively simple example. Suppose we ask you to ask DrRacket to compute the square root of 137641. You should be able to do so by entering an appropriate Scheme expression:

> (sqrt 137641)

DrRacket will give you an answer. How can you test the correctness of this answer? What if you don’t trust DrRacket’s multiplication procedure? (Be prepared to answer this question for the class as a whole.)

Exercise 4: DrRacket’s definitions pane

Short Version

  • The interactions pane is temporary. The top pane, called the definitions pane is more permanent.
  • When you click Run, the interactions pane is erased and the instructions in the definitions pane are executed.
  • Enter the definitions from the reading. (Those definitions are repeated below.)
  • Ask DrRacket to compute the average and maximum rating.
  • Since you’ve taken work from elsewhere, insert a short citation.

Detailed Version

As you may recall from the reading, the upper text area in the DrRacket window, which is called the definitions pane, is used when you want to prepare a program “off-line”, that is, without immediately executing each step. Instead of processing what you type line by line, DrRacket waits for you to click on the button labeled Run (the second button from the right, in the row just below the menu bar) before starting to execute the program in the definitions pane. If you never click on that button, fine – your program is never executed.

Let’s try using the definitions pane. First, enter the following definitions from the reading in that pane.

#lang racket
(define tribune-rating 4.5)
(define cbs-rating 3.5)
(define nbc-rating 4)
(define abc-rating 5)
(define fox-rating 3)

Next, try computing the average in the interactions pane.

> (/ (+ times-rating tribune-rating cbs-rating nbc-rating abc-rating fox-rating) 6)
Error! reference to undefined identifier: times-rating
Error! Interactions:1:0: times-rating

It is likely that you will get an error message, just as the example suggests. Why? (Please make sure you have an answer before going on.)

As you’ve discovered, we are missing a definition for times-rating. Add one.

Next, click Run and try entering the expression again. (Remember, the Ctrl-UpArrow will bring back the previous expression.)

Note: We have tried to style the code for the definitions pane differently than we’ve formatted the code for the interactions pane. We’ll try to be consistent, so that you can better tell where instructions are to go.

You’ve copied code from elsewhere. That means that you have a responsibility to insert a “comment” that cites the original authors. In Scheme, comments start with a semicolon and end at the end of the line. Here’s one possible citation.

; The following definitions are taken from
;   Curtsinger, C., Davis, J., Hamid, F., Klinge, T., Rebelsky, S., and Weinman, J. (2018).  
;   The DrRacket Programming Environment.  Online document available at 
;   _URL_.

Insert that citation, using the appropriate URL.

Note: You may encounter different expectations about the appropriate form of citations. Make it a habit to start by copying and pasting the URL of a document whenever you copy and paste code. Doing so shows that you have the appropriate intent. If you are expected to provide a full citation, you can go back later and add it.

Exercise 5: Definitions, revisited

Let’s try another definition. Define name as your name in quotation marks. For example,

(define name "Charlie")

Click Run and then find the value of the following expression.

> (string-append "Hello " name)

Exercise 6: Saving to Files

Let’s make sure that you can save and restore the work you do in the definitions pane. The source and destination names are displayed as paths below, but DrRacket uses a file browser to help you choose a file to load or save. Remember that the ~ character is shorthand for your home directory, which you can access by clicking the Home button on the left of the file browser DrRacket shows when you are saving or loading files.

  • Save your definitions as ~/Desktop/ratings.rkt
  • Quit DrRacket.
  • Restart DrRacket.
  • In DrRacket, open ~/Desktop/ratings.rkt.
  • Click Run
  • In the interactions pane, enter the expressions from above
    • (/ (+ times-rating tribune-rating cbs-rating nbc-rating abc-rating fox-rating) 6)
    • (string-append "Hello " name)

Exercise 7: Loading definitions

Let’s try using the definitions you created without having them open in the definitions pane.

  • Add a new rating, sandb-rating, to ratings.rkt. You can choose the value to associate with this rating.
  • Add the following incantation to the top of your definitions window, immediately below the line that says #lang racket. This line tells Racket that other programs can access your definitions.
    (provide (all-defined-out))
  • Save ratings.rkt, but do not run it.
  • Quit DrRacket.
  • Restart DrRacket.
  • In the interactions pane of the new window, type sandb-rating. You should get an error message, which tells you that sandb-rating is not yet defined.
  • In the interactions pane of the new window, type
    > (require Desktop/ratings)
  • In the interactions pane, type sandb-rating. You should now see a value.

In the future, we will be creating some .rkt files that contain definitions that we change infrequently. Those files we will require, rather than open.

Exercise 8: Other notations

As you’ve learned, Scheme expects you to use parentheses and prefix notation when writing expressions. What happens if you use more traditional mathematical notation? Let’s explore that question.

Type each of the following expressions at the Scheme prompt and see what reaction you get.

  • (2 + 3)
  • 7 * 9
  • sqrt(49)
  • (+ (87) (23))

You may wish to read the notes on this problem for an explanation of the results that you get.

For Those with Extra Time

Extra 1: Definitions, Revisited

As you observed in the primary exercises for this laboratory, you can use the definitions pane to name values that you expect to use again (or that you simply find it more convenient to refer to with a mnemonic). So far, all we’ve named is simple values. However, you can also name the results of expressions.

a. In the definitions pane, write a definition that assigns the name seconds-per-minute to the value 60.

b. In the definitions pane, write a definition that assigns the name minutes-per-hour to the value 60.

c. In the definitions pane, write a definition that assigns the name hours-per-day to the value 24.

d. In the definitions pane, write a definition that assigns the name seconds-per-day to the product of those three values. Note that you should use the following expression to express that product.

(* seconds-per-minute minutes-per-hour hours-per-day)

e. Run your definitions and confirm in the interactions pane that seconds-per-day is defined correctly.

f. Optionally, create a .rkt file to store those definitions.

Extra 2: Grading

Let’s play for a bit with how one might use DrScheme to compute grades. (We teach you this, in part, so that you can figure out your estimated grade in this class and others.) Let’s define five names, grade1 through grade5 that potentially represent grades on five homework assignments.

(define grade1 95)
(define grade2 93)
(define grade3 105)
(define grade4 30)
(define grade5 80)

Looking at those grades, you might observe that the student seems to have spent a bit of extra work on the third assignment, but that the extra work so disrupted the student’s life that the next assignment was a disaster. (You may certainly analyze the grades differently.)

a. Write a definition that assigns the name average-grade to the average of the grades.

Many faculty members discard these “outliers”, with a grading policy of “I take the average of your grades after dropping the highest grade and the lowest grade”.

b. Write a definition that assigns the name highest-grade to a computed highest grade. (That is, highest-grade should remain correct, even if I change the values associated with grade1 through grade5.) In writing this definition, you may find the max procedure useful.

c. Write a definition that assigns the name lowest-grade to a computed lowest grade. You may find the min procedure useful.

d. Write a definition that assigns the name modified-average to the modified average grade (that is, the grade that results from dropping the lowest and highest grades and then averaging the result).

Notes on the Exercises

Notes on Exercise 8: Other notations

> (2 + 3)
Error! procedure application: expected procedure, given: 2; arguments were: #<procedure:+> 3
Error! Interactions:1:0: ((quote 2) + (quote 3))

When the Scheme interpreter sees the left parenthesis at the beginning of the expression (2 + 3), it expects the expression to be a procedure call, and it expects the procedure to be identified right after the left parenthesis. But 2 does not identify a procedure; it stands for a number. (A “procedure application” is the same thing as a procedure call.)

> 7 * 9

In the absence of parentheses, the Scheme interpreter sees 7 * 9 as three separate and unrelated expressions – the numeral 7; *, a name for the primitive multiplication procedure; and 9, another numeral. It interprets each of these as a command to evaluate an expression: “Compute the value of the numeral 7! Find out what the name * stands for! Compute the value of the numeral 9!” So it performs the first of these commands and displays 7; then it carries out the second command, reporting that * is the name of the primitive procedure *; and finally it carries out the third command and displays the result, 9. This behavior is confusing, but it’s strictly logical if you look at it from the computer’s point of view (remembering, of course, that the computer has absolutely no common sense).

> sqrt(49)
Error! procedure application: expected procedure, given: 49 (no arguments)
Error! Interactions:1:4: ((quote 49))

As in the preceding case, DrRacket sees sqrt(49) as two separate commands: sqrt means “Find out what sqrt is!” and (49) means “Call the procedure 49, with no arguments!” DrRacket responds to the first command by reporting that sqrt is the primitive procedure for computing square roots and to the second by pointing out that the number 49 is not a procedure.

Return to the problem