Prologue: How to Program
Consider a quick look
at On Teaching Part I.
When you were a small child, your parents probably taught you to count and
later to perform simple calculations with your fingers: “1 + 1 is 2”; “1 +
2 is 3”; and so on. Then they would ask “what’s 3 + 2” and you would count
off the fingers of one hand. They programmed, and you computed. And in
some way, that’s really all there is to programming and computing.
Start DrRacket and select “Choose language” from the
“Language” menu. This brings up a dialog listing “Teaching Languages”
for “How to Design Programs” (and possibly other books). Choose
“Beginning Student Language” and “OK” to set up DrRacket for this chapter.
Now you’re switching roles. You program, and the computer is a child. Of
course, you start with the simplest of all calculations. You type
into the top part of DrRacket, click RUN, and a result shows up in the
bottom part: 2
Figure 3: Meet DrRacket
That’s how simple programming is. You ask questions as if DrRacket were
a child, and DrRacket computes for you. People often say the
“computer does X for you” but in reality, a plain computer is pretty
useless. It is software that computes.
You can also ask DrRacket to process several
requests at once:
|(+ 2 2)|
|(* 3 3)|
|(- 4 2)|
|(/ 6 2)|
After you click RUN, you see
4 9 2 3
in the bottom half of DrRacket, which are the expected results.
Terminology At this point, we slow down for a moment and introduce
The top-half of DrRacket is called the definitions area. In
this area, you create the programs, which is called editing. As
soon as you add a word or change something in the definitions area, the
SAVE button shows up in the top-left corner. When you click
SAVE for the first time, DrRacket asks you for the name of a file so
that it can store your program for good. Once your definitions area is
associated with a file, clicking SAVE ensures that the
content of the definitions area is stored safely in the file.
Programs consist of expressions. You have seen
expressions in mathematics. For now, an expression is either a plain
number or something that starts with a left parenthesis “(” and ends in
a matching right parenthesis “)”—which DrRacket rewards by shading the
area between the pair of parentheses.
When you click RUN, DrRacket evaluates the expressions in the
definitions area and shows their result in the interactions
area. Then, DrRacket, your faithful servant, awaits your commands at the
prompt. The appearance of the prompt signals that DrRacket is
waiting for you to enter additional expressions, which it then evaluates
like those in the definitions area:
Enter an expression at the prompt, hit the “return” or “enter” key on
your keyboard, and watch how DrRacket responds with the result. You can do
so as often as you wish:
Take a close look at the last number. Its “#i” prefix is short for “I
don’t really know the precise number so take that for now” or
inexact number. Unlike your
calculator or most other programming systems, DrRacket is extremely
honest. When it doesn’t know the exact number, it warns you with this
special prefix. Later, we shall show you really strange facts about
“computer numbers,” and you will then truly appreciate that DrRacket
issues such warnings.
Enough terminology for now.
By now, you might be wondering whether DrRacket can add more than two
numbers at once, and yes, it can! As a matter of fact, it can do it in two
|> (+ 2 (+ 3 4))|
|> (+ 2 3 4)|
The first one is nested arithmetic, as you know it from school.
The second one is Racket arithmetic and it is natural, if you
always use parentheses to group operations and numbers
together. This is as a good a time as any to discuss the nature of
our notation—dubbed Beginning Student Language or just
BSL—something you might have pondered for a while now.
This book does not teach you Racket, even if the software is
called DrRacket. Instead it uses a series of teaching languages created for
learning design principles. Once you have mastered these languages, you
can quickly learn to program in all kinds of programming languages,
In BSL, every time you want to use a “calculator operation,” you write
down an opening parenthesis followed by the operation, the numbers on
which the operation should work (separated by spaces or even line breaks),
and ended by a closing parenthesis. The items following the operation are
called the operands. Nested arithmetic means that you can use an
expression for an operand, which is why
is a fine program. You can do this as often as you wish:
|> (+ 2 (+ (* 3 3) 4))|
|> (+ 2 (+ (* 3 (/ 12 4)) 4))|
|> (+ (* 5 5) (+ (* 3 (/ 12 4)) 4))|
There are no limits to nesting, except for your patience.
Naturally, when DrRacket calculates for you, it uses the rules that you know
and love from math. Like you, it can determine the result of an addition
only when all the operands are plain numbers. If an operand is a
parenthesized operator expression—something that starts with a “(” and
an operation—it determines the result of that nested expression
first. Unlike you, it never needs to ponder which expression to
calculate first—because this first rule is the only rule there is to
The price for DrRacket’s convenience is that parentheses have meaning. You,
the programmer, must enter all these parentheses, and you may not enter too
many. For example, while extra parentheses are acceptable to your math
teacher, this is not the case for BSL. The expression (+ (1) (2))
contains way too many parentheses, and DrRacket lets you know in no uncertain terms:
|> (+ (1) (2))|
function call: expected a function after the open parenthesis, but found a number
Once you get used to BSL programming though, you will see that it
isn’t a price at all. First, you get to use operations on several
operands at once, if it is natural to do so:Or you place the
cursor next to the operation and hit F1. This action opens DrRacket’s HelpDesk
and searches for the documentation of the operation. Use the results
concerning the HtDP teaching languages. As you may have noticed by now,
this text is also linked to the documentation in HelpDesk.
|> (+ 1 2 3 4 5 6 7 8 9 0)|
|> (* 1 2 3 4 5 6 7 8 9 0)|
If you don’t know what an operation does for several operands, enter an
example into the interactions area and hit "return"; DrRacket lets
you know whether and how it works. Second, when you will read programs that
others write—which you will do for about half the time of your
programmer life—you will never have to wonder which expressions are
evaluated first. The parentheses and the nesting will immediately tell
In this context, to program is to write down comprehensible, arithmetic
expressions, and to compute is to determine their value. With DrRacket, it is
easy to explore this kind of programming and computing.
Arithmetic and Arithmetic
If programming were just about numbers and arithmetic, it would be as
boring as mathematics.Just kidding: mathematics is a fascinating
subject, but you knew that. You won’t need too much of it for now, though
if you want to be a really great programmer, you will need to study some.
Fortunately, there is much more to programming than numbers: text,
truths, images, and more.
Here are three programs that deal with text:
After you click RUN, DrRacket displays three results:
"helloworld" "hello world" "hello world"
To understand exactly what’s going on, you first need to know that in BSL,
text is any sequence of keyboard characters enclosed in double-quotes
("). Technically, this is called a string. Thus,
"hello world", is a perfectly fine string and, when DrRacket evaluates this
string, it displays it in the interactions area, just like a number.
Indeed, many people’s first program is one that displays the words
“hello” and “world”—you wrote three of them already but the simplest one is to type
in the string by itself:
Click RUN and admire the output of the program.
Otherwise, you need to know that in addition to an arithmetic of numbers,
DrRacket also knows about an arithmetic of strings. Thus,
is an operation just like +
; it makes a
string by adding the second to the end of the first. As the first line
shows, it does this literally, without adding anything between the two
strings: no blank space, no comma, nothing. Thus, if you want to see the
phrase "hello world"
, you really need to add a space to one of
these words somewhere; that’s what the second and third line show. Of
course, the most natural way to create this phrase from the two words is
, like +
, can deal with as many
operands as you wish.
You can do more with strings than append them. You can extract pieces from
a string; reverse them; render all letters uppercase (or lowercase); strip
blanks spaces from the left and right; and so on. And best of all, you
don’t have to memorize any of that. If you need to know what you can do
with strings, look it up in HelpDesk. Use F1 or the drop-down
menu on the right to open HelpDesk, look at the manuals for HtDP languages
(Beginning Student Language) and its section on pre-defined operations. It lists all the operations
and especially those that work on strings.
If you did look up the primitive operations of BSL, you saw that
primitive (sometimes called pre-defined or built-in) operations can consume
strings and produce numbers. You therefore can, if you so desire,
add the length of a string to 20:
and DrRacket evaluates this expressions like any other one.
That is, an arithmetic operation doesn’t have to be about just numbers or
just strings. Many of them mix and match as needed. And then there are
operations that convert strings into numbers and numbers into strings and
you get what you expect:
If you expected “forty-two” or something clever along those lines,
sorry, that’s really not what you want from a string calculator.
The second expression raises a question, though. What if string->number
isn’t used with a string that is a number wrapped in string quotes? In that
case the operation produces a totally different kind of result:
This is neither a number nor a string; it is a Boolean. Unlike numbers
and strings, Boolean values come in only two varieties: #true and
#false. The first is truth, the second falsehood. Even so, DrRacket
has several operations for combining Boolean values:
|> (and #true #true)|
|> (and #true #false)|
|> (or #true #false)|
|> (or #false #false)|
|> (not #false)|
and you get the results that the name of the operation suggests. (Don’t
know what and
, and not
(and x y)
is true if x
(or x y)
is true if either x
or both are
true; and (not x)
results in #true
Although it isn’t possible to convert one number into a Boolean, it is certainly
useful to “convert” two numbers into a Boolean:
Guess what the results are before you move on:
Now try these: (>= 10 10), (<= -1 0), and
(string=? "design" "tinker"). This last one is totally different
again but don’t worry, you can do it.
With all these new kinds of data—yes, numbers, strings, and
Boolean values are data—and operations floating around, it is easy to
forget some basics, like nested arithmetic:
What is the result of this expression? How did you figure it out? All by
yourself? Or did you just type it into DrRacket’s interactions area
and hit the "return" key? If you did the latter, do you think you would
know how to do this on your own? After all, if you can’t predict what
DrRacket does for small expressions, you may not want to trust it when
you submit larger tasks than that for evaluation.
Before we show you how to do some “real” programming, let’s discuss one
more kind of data to spice things up: images. To insert
images such as this rocket into DrRacket, use the Insert menu and
select the ``Insert image ...'' item. Or, if you’re reading this book
on-line, copy-and-paste the image from your browser into DrRacket. When you
insert an image into the interactions area and hit return like this
DrRacket replies with the image. In contrast to many other programming
languages, BSL understands images, and it supports an arithmetic of
images just as it supports an arithmetic of numbers or strings. In short,
your programs can calculate with images, and you can do so in the
interactions area. Furthermore BSL programmers—like the programmers for
other programming languages—create libraries that others may
find helpful. Using such libraries is just like expanding your
vocabularies with new words or your programming vocabulary with new
primitives. We dub such libraries teachpacks because they are
helpful with teaching.
(require 2htdp/image) specifies that you wish to add
the definitions of the 2htdp/image library to your program. Alternatively, use the
“Language” drop-down menu, choose ``Add Teachpack ...'' and pick
2htdp/image from the Preinstalled HtDP/2e Teachpack menu.
One important library—the 2htdp/image library
supports operations for computing
the width and height of an image:
Once you have added the library to your program, clicking RUN gives
because that’s the area of a 28 by 42 image.
You don’t have to use Google to find images and insert them in your DrRacket
programs with the “Insert” menu. You can also instruct DrRacket to
create simple images from scratch:
Best of all, DrRacket doesn’t just draw images, because it really considers
them values just like numbers. So naturally BSL has operations for
combining images just like it has operations for adding numbers or
Overlaying the same images in the opposite order produces a solid blue
Stop and reflect on this last result for a moment.
As you can see overlay
is more like string-append
, but it does “add” images just like string-append
“adds” strings and +
adds numbers. Here is another illustration
of the idea:
These interactions with DrRacket don’t draw anything at all; they really just
measure their width.
You should know about two more operations: empty-scene
. The first creates a scene, a special kind of
rectangle. The second places an image into such a scene:
and you get this: Not quite. The image comes without a
grid. We superimpose the grid on the empty scene so that you can see
where exactly the green dot is placed.
As you can see from this image, the origin (or (0,0)) is in the upper-left
corner. Unlike in mathematics, the y-coordinate is measured
downwards, not upwards. Otherwise, the image shows what you should
have expected: a solid green disk at the coordinates (50,80) in a 100 by
100 empty rectangle.
Let’s summarize again. To program is to write down an arithmetic
expression, but you’re no longer restricted to boring numbers. With BSL,
your arithmetic is the arithmetic of numbers, strings, Boolean values, and
even images. To compute though still means to determine the value of the
expressions(s) except that this value can be a string, a number, a
Boolean, or an image.
And now you’re basically ready to write programs that make rockets fly.
Inputs and Output
The programs you have written so far are pretty boring. You write down an
expression or several expressions; you click RUN; you see some
results. If you click RUN again, you see the exact same results. As
a matter of fact, you can click RUN as often as you want, and the
same results show up. In short, your programs really are like calculations
on a pocket calculator, except that DrRacket calculates with all kinds
of data not just numbers.
That’s good news and bad news. It is good because programming and computing
ought to be a natural generalization of using a calculator. It is bad
because the purpose of programming is to deal with lots of data and to get
lots of different results, with more or less the same calculations. (It
should also compute these results quickly, at least faster than we can.)
That is, you need to learn more still before you know how to program. No
need to worry though: with all your knowledge about arithmetic of numbers,
strings, Boolean values, and images, you’re almost ready to write a program
that creates movies, not just some silly program for displaying “hello
world” somewhere. And that’s what we’re going to do next.
Just in case you didn’t know, a movie is a sequence of images that are
rapidly displayed in order. If your algebra teachers had known about the
“arithmetic of images” that you saw in the preceding section, you could
have produced movies in algebra instead of boring number
sequences. Remember those tables that your teachers would show you? Here is
Your teachers would now ask you to fill in the blank, i.e., replace the “?”
mark with a number.
It turns out that making a movie is no more complicated than completing a
table of numbers like that. Indeed, it is all about such tables:
To be concrete, your teacher should ask you here to draw the sixth image,
the seventh, and the 1273rd one because a movie is just a lot of
images, some 20 or 30 of them per second. So you need some 1200 to 1800
of them to make one minute’s worth of it.
You may also recall that your teacher not only asked for the fifth, sixth,
or seventh number in some sequence but also for an expression that
determines any element of the sequence from a given x. In the
numeric example, the teacher wants to see something like
If you plug in 1, 2, 3, and so on for x, you get 1, 4, 9, and so on for
y—just as the table says. For the sequence of images, you could say
y = the image that contains a dot x2 pixels below the top.
The key is that these one-liners are not just expressions but functions.
At first glance functions are like expressions, always with a y on the
left, followed by an = sign, and an expression. They aren’t expressions,
however. And the notation you (usually) learn in school for functions is
utterly misleading. In DrRacket, you therefore write functions a bit
says “consider y
a function”, which like
an expression, computes a value. A function’s value, though, depends on
the value of something called the input
, which we express with
. Since we
don’t know what this input is, we use a name to represent the
input. Following the mathematical tradition, we use x
to stand in for the unknown input but pretty soon, we shall use all kinds
This second part means you must supply one value—a number—for
x to determine a specific value for y. When you do,
DrRacket plugs in the value for x into the expression
associated with the function. Here the expression is (* x x). Once x is replaced with a value, say 1, DrRacket
can compute the result of the expressions, which is also called the
output of the function.
Click RUN and watch nothing happen. Nothing shows up in the
interactions area. Nothing seems to change anywhere else in
DrRacket. It is as if you hadn’t accomplished anything. But you
did. You actually defined a function and informed DrRacket about its
existence. As a matter of fact, the latter is now ready for you to use the
at the prompt in the interactions area and watch a 1 appear in
response. The (y 1) is called a function application in
DrRacket.... and in mathematics, too. Your teachers just
forgot to tell you. Try
and see a 4 pop out. Of course, you can also enter all these
expressions in the definitions area and click RUN:
|(define (y x) (* x x))|
In response, DrRacket displays:
1 4 9 16 25,
which are the numbers from the table. Now determine the missing entry.
What all this means for you is that functions provide a rather economic way
of computing lots of interesting values with a single expression. Indeed,
programs are functions, and once you understand functions well, you know
almost everything there is about programming. Given their importance,
let’s recap what we know about functions so far:
(define (FunctionName InputName) BodyExpression)
is a function definition
. You recognize it as such, because it
starts with the “define
” keyword. A function definition
consists of three pieces: two names and an expression. The first name is
the name of the function; you need it to apply the function as often as
you wish. The second name—
most programmers call it a
represents the input of the function, which is
unknown until you apply the function. The expression, dubbed
computes the output of the function for a specific
input. As seen, the expression involves the parameter, and it may also
consist of many other expressions.
is a function application. The first part tells DrRacket which
function you wish to use. The second part is the input to which you want
to apply the function. If you were reading a Windows or a Mac manual, it
might tell you that this expression “launches” the (software)
“application” called FunctionName and that it is going to
process ArgumentExpression as the input. Like all expressions,
the latter is possibly a plain piece of data (number, string, image,
Boolean) or a complex, deeply nested expression.
Functions can input more than numbers, and they can output all kinds of
data, too. Our next task is to create a function that simulates the
the one with images of a colored dot—
just like the first
function simulated the numeric table. Since the creation of images from
expressions isn’t something you know from high school, let’s start
simply. Do you remember empty-scene
? We quickly mentioned it at
the end of the previous section. When you type it into the definitions
area, like that:
clicking RUN produces an empty rectangle, also called a scene:
produces a scene with a rocket hovering near the center of the top:
Think of the rocket as an object that is like the dot—though more
interesting—in the above table from your mathematics class.
Next you should make the rocket descend, just like the dot in the above
table. From the preceding section you know how to achieve this effect by
increasing the y-coordinate that is supplied to place-image
Clicking RUN yields three scenes:
All that’s needed now is to produce lots of these scenes easily and to
display all of them in rapid order.
The first goal can be achieved with a function of course:
Yes, this is a function definition. Instead of y, it uses the
name create-rocket-scene, a name that immediately tells you what
the function outputs: a scene with a rocket. Instead of x, the
function definition uses height for the name of its parameter, a
name that suggests that it is a number and that it tells the function
where to place the rocket. The body expression of the function is just
like the series of expressions with which we just experimented, except
that it uses height in place of a number. And we can easily
create all of those images with this one function:
Try this out in the definitions area or the interactions area, both
create the expected scenes.
Now add the 2htdp/universe library to your definitions.
The second goal requires knowledge about one additional primitive operation
from the 2htdp/universe library
. So, add the
line to the definitions area, click RUN
enter the following expression:
Stop for a moment and note that the argument expression is a function. Don’t
worry for now about using functions as arguments; it works well with
but don’t try this at home yet.
As soon as you hit the “return” key, DrRacket evaluates the expression but
it does not display a result, not even an interactions prompt (for a
while). It opens another window—a canvas—and starts a clock
that ticks 28 times per second. Every time the clock ticks, DrRacket
applies create-rocket-scene to the number of ticks passed since
this function call. The results of these function calls are displayed in
the canvas, and it produces the effect of an animated movie. The
simulation runs until you click STOP or close the window. At that
point, animate returns the number of ticks that have passed.
The question is where the images on the window come
from.Exercise 284 explains how to design
The short explanation is that animate
operand on the numbers 0
, etc. and
displays the resulting images. The long explanation is this:
animate starts a clock, and animate counts the
number of clock ticks;
the clock ticks 28 times per second;
every time the clock ticks, animate applies the function
create-rocket-scene to the current clock tick; and
the scene that this application creates is displayed on the screen.
This means that the rocket first appears at height 1, then
2, then 3, etc., which explains why the rocket descends
from the top of the screen to the bottom. That is, our three-line program
creates some 100 pictures in about 3.5 seconds, and displaying these
pictures rapidly creates the effect of a rocket descending to the ground.
Here is what you learned in this section. Functions are useful because they
can process lots of data in a short time. You can launch a function by
hand on a few select inputs to ensure it produces the proper outputs. This
is called testing a function. Or, DrRacket can launch a function on lots of
inputs with the help of some libraries; when you do that, you are running
the function. Naturally, DrRacket can launch functions when you press a key
on your keyboard or when you manipulate the mouse of your computer. To
find out how, keep reading. Whatever triggers a function application isn’t
important, but do keep in mind that (simple) programs are just functions.
Many Ways To Compute
When you run the create-rocket-scene program from the preceding
section, the rocket eventually disappears in the ground. That’s plain
silly. Rockets in old science fiction movies don’t sink into the ground;
they gracefully land on their bottoms, and the movie should end right
This idea suggests that computations should proceed differently, depending
on the situation. In our example, the create-rocket-scene program
should work “as is” while the rocket is in-flight. When the rocket’s
bottom touches the bottom of the screen, however, it should stop the
rocket from descending any further.
In a sense, the idea shouldn’t be new to you. Even your mathematics
teachers define functions that distinguish various situations:
This sign distinguishes three kinds of inputs: those
numbers larger than 0, those equal to 0, and those smaller than 0. Depending on the
input, the result of the function—or output as we may occasionally call
it—is +1, 0, or -1.
Open a new tab in DrRacket and start with a clean slate.
You can define this function in DrRacket without much ado using a
|(define (sign x)|
| [(> x 0) 1]|
| [(= x 0) 0]|
| [(< x 0) -1]))|
To illustrate how sign works, we added three applications of the
function to the definitions area. If you click RUN, you see
1, -1, and 0.
This is a good time to explore what the STEP button
does. Click STEP for the above sign program. When the
new window comes up, click the right and left arrows there.
In general, a conditional expression has the shape
| [ConditionExpression1 ResultExpression1]|
| [ConditionExpression2 ResultExpression2]|
| [ConditionExpressionN ResultExpressionN])|
That is, a cond
itional expressions consists of many
. Each line contains two expressions: the left
one is often called condition
and the right one is called
. To evaluate a cond
evaluates the first condition expression, ConditionExpression1
If this evaluation yields #true
DrRacket replaces the cond
expression with the first result
) and evaluates it. Whatever value
DrRacket obtains is the result of the entire cond
If the evaluation of ConditionExpression1
DrRacket drops the first line and moves on to the second line, which is
treated just like the first one. In case all condition expressions
evaluate to #false
, DrRacket signals an error.
Figure 4: Landing a rocket (version 2)
With this knowledge, you can now change the course of the simulation. The
goal is to not let the rocket descend below the ground level of a
100 by 100 scene. Since the create-rocket-scene function consumes
the height at which it is to place the rocket in the scene, a simple test
comparing the given height to the maximum height appears to suffice.
See figure 4
for the revised function definition.
In BSL, you can really use all kinds of characters in
function names, including “.” or “-” which you have already seen.
call the revised function create-rocket-scene.v2
to distinguish it from the original
version. Doing so also allows us to use both functions in the interactions
area of DrRacket and to compare their results:
|> (create-rocket-scene 5555)|
|> (create-rocket-scene.v2 5555)|
No matter what number over 100 you give to
create-rocket-scene.v2, you get the same scene. In
particular, when you run the simulation
the rocket descends, sinks half way into the ground, and finally comes to
Landing the rocket half-way under ground is ugly. Then again, you basically
know how to fix this aspect of the program. As you learned from the
preceding sections, DrRacket knows an arithmetic of images. Images have
a center point and, when place-image adds an image to a scene, it
uses this center point as if it were the image. This explains why the
rocket is half way under ground at the end: DrRacket thinks of the
image as if it were a point, but the image has a real height and a real
width. As you may recall, you can measure the height of an image with the
operation image-height, which is to images like + is to
numbers. This function comes in handy here because you really want to fly
the rocket only until its bottom touches the ground.
Putting one and one together—also known as playing around—you can now
figure out that
is the point at which you want the rocket to stop its descent. Hint You
could figure this out by playing with the program directly. Or you can
experiment in the interactions area with your image arithmetic. Enter
this expression, which is one natural guess:
and then this one:
Which result do you like better?
Figure 5: Landing a rocket (version 3)
When you think and experiment along these lines, you eventually get to the
program in figure 5.
Given some number, which represents the height of the rocket, it
first tests whether the rocket’s bottom is above the ground. If it is, it
places the rocket into the scene as before. If it isn’t, it places the
rocket’s image so that its bottom touches the ground.
One Program, Many Definitions
Now imagine this. Your manager at your hot game company doesn’t like the
size of your program’s canvas and requests a version that uses
200 by 400 scenes. This simple request forces you to
replace 100 with 400 in five places in the program, which
includes the animate line, and to replace 100 with
200 in two other places—not to speak of the occurrences of
50, which really suggest “middle of the canvas.”
Stop! Before you read on, try to do just that so that you get an idea of
how difficult it is to execute this request for a five-line program. As
you read on, keep in mind that real programs consists of 50,000 or 500,000
or 5,000,000 lines of program code.
In the ideal program, a small request, such as changing the sizes of the
canvas, should require an equally small change. The tool to achieve this
simplicity with BSL is define
. In addition to defining functions,
you can also introduce constant definitions
, which assign some
name to a constant. The general shape of a constant definition is
Thus, for example, if you write down
in your program, you are saying that HEIGHT always
represents the number 100. The meaning of such a definition is
what you expect. Whenever DrRacket encounters HEIGHT during its
calculations, it uses 100 instead. Of course, you can also add
to your program to have one single place where you specify the width of
Figure 6: Landing a rocket (version 4)
Now take a look at the code in figure 6
, which implements this
simple change. Copy the program into DrRacket, and after clicking
, evaluate the following interaction:
Confirm that the program still functions as before.
The program in figure 6 consists of three definitions: one
function definition and two constant definitions. The number
100 occurs only twice: once as the value of WIDTH and
once as the value of HEIGHT. The last line starts the
simulation, just as in version 3 of the program. You may also have noticed
that it uses h instead of height for the function
parameter of create-rocket-scene.v4. Strictly speaking, this
change isn’t necessary because DrRacket doesn’t confuse height with
HEIGHT but we did it to avoid confusing you.
When DrRacket evaluates (animate create-rocket-scene.v4),
it replaces HEIGHT with 100 and WIDTH with 100
every time it encounters these names. To experience the joys of real
programmers, change the 100 next to HEIGHT into a 400
and click RUN. You see a rocket descending and landing in a 100 by 400
scene. One small change did it all.
In modern parlance, you have just experienced your first program
refactoring. Every time you re-organize your program to prepare yourself
for likely future change requests, you refactor your program. Put it on
your resume. It sounds good, and your future employer probably enjoys
reading such buzzwords, even if it doesn’t make you a good programmer.
What a good programmer would never live with, however, is that the program
contains the same expression three times:
Every time your friends and colleagues read this program, they need to
understand what this expression computes, namely, the distance between the
bottom of the screen and the center point of a rocket resting on the
ground. Every time DrRacket computes the value of the expressions it
has to perform three arithmetic operations: (1) determine the height of the
image; (2) divide it by 2; and (3) subtract the result from
HEIGHT. And every time it comes up with the same number.
This observation calls for the introduction of one more definition to your
plus the replacement of every other occurrence of (- HEIGHT (/ (image-height ) 2))
You might wonder whether the new definition should be placed
above or below the definition for HEIGHT
. More generally, you should
be wondering whether the ordering of definitions matters. The answer is that
for constant definitions, the order matters, and for function definitions
it doesn’t. As soon as DrRacket encounters a constant definition, it
determines the value of the expression and then associates the name with
this value. Thus, for example,
is meaningless because DrRacket hasn’t seen the definition for
CENTER yet when it encounters the definition for
HEIGHT. In contrast,
works as expected. First, DrRacket associates CENTER
. Second, it evaluates (* 2 CENTER)
, which yields
. Finally, DrRacket associates 200
While the order of constant definitions matters, it doesn’t matter whether
you first define constants and then functions or vice versa. Indeed, if
your program consisted of more than one function, it wouldn’t matter in
which order you defined those. For pragmatic reasons, it is good to
introduce all constant definitions first, followed by the definitions of
important functions, with the less important ones bringing up the rear
guard. When you start writing your own multi-definition programs, you will
soon see why this ordering is a good idea.
Figure 7: Landing a rocket (version 5)
The program also contains two line comments,
introduced with semi-colons (“;”). While DrRacket ignores such comments,
people who read programs should not because comments are intended for
human readers. It is a “back channel” of communication between the
author of the program and all of its future readers to convey information
about the program.
Once you eliminate all repeated expressions, you get the program in
figure 7. It consists of one function definition and five
constant definitions. Beyond the placement of the rocket’s center, these
constant definitions also factor out the image itself as well as the
creation of the empty scene.
Before you read on, ponder the following changes to your program:
How would you change the program to create a 200 by 400 scene?
How would you change the program so that it depicts the landing of a
green UFO (unidentified flying object)? Drawing the UFO per se is easy:
How would you change the program so that the background is always
How would you change the program so that the rocket lands on a flat rock
bed that is 10 pixels higher than the bottom of the scene? Don’t forget to
change the scenery, too.
Better than pondering is doing. It’s the only way to learn. So don’t let
us stop you. Just do it.
Magic Numbers Take another look at the definition of
create-rocket-scene.v5. As we eliminated all repeated
expressions, all but one number disappeared from this function
definition. In the world of programming, these numbers are called
magic numbers, and nobody likes them. Before you know it, you
forget what role the number plays and what changes are legitimate. It is
best to name such numbers in a definition.
Here we actually know that 50 is our whimsical choice for an
x-coordinate for the rocket. Even though 50 doesn’t look
like much of an expression, it actually is a repeated expression, too.
In other words, we have two reasons to eliminate 50 from the
function definition, and we leave it to you to do so.
One More Definition
Danger ahead! This section introduces one piece of knowledge
from physics. If physics scares you, skip this section on a first reading;
programming doesn’t require physics knowledge.
Real rockets don’t descend at a constant speed. Real cars don’t stop on the
spot. They decelerate, meaning they gradually reduce their speed. To
understand how this process works, you must think back to your physics
courses. If you haven’t because you’re too young or if you can’t remember
because you’re too old or if you fell asleep in the course, you’ll need to
consult a physics book. Don’t worry. This happens to programmers all the
time because they need to help people with problems in music, physics, mechanical
engineering, economics, photography, and all kinds of other disciplines
and, obviously, not even programmers know everything. So they look it
up. Or they are told what deceleration means in terms of distance
That is, if the speed of an object changes at a rate of a, then the
object travels d miles (or meters or pixels or whatever) in
By now you know that a good teacher would show you a proper function definition:
because this tells everyone immediately that the computation of d
depends on t and that v and a are constants. A
programmer goes even further and uses meaningful names for these
This program consists of two definitions: a function that computes the
distance traveled by a decelerating object, and a constant that describes
its change in speed or deceleration. The distance
function uses a
primitive operator called sqr
; if you can’t figure out what it
does, play with it in the interactions area or look it up in HelpDesk.
The only other thing you need to know is that animate
applies its functions to the number of clock ticks that have passed since
it was first called and not
the height of the rocket image. From
this revelation it immediately follows that our five versions of
have thus far used the wrong name for the
input. Clearly, t
short for time—
would be much better than
, which is short for height:
|(define (create-rocket-scene t)|
| [(<= t ROCKET-CENTER-TO-BOTTOM)|
| (place-image ROCKET X t MTSCN)]|
| [(> t ROCKET-CENTER-TO-BOTTOM)|
| (place-image ROCKET X ROCKET-CENTER-TO-BOTTOM MTSCN)]))|
This small change to the definition immediately clarifies that this program
uses time as if it were a distance, a bad idea.
Figure 8: Landing a rocket (version 6)
Even if you have never taken a physics course, you know that a time is not
a distance. So somehow our program worked by accident. Don’t worry,
though; it is all easy to fix. Instead of t use
(distance t) and you’ve got a distance, which it makes sense to
compare to other distances.
The final program is displayed in figure 8
. It consists of two
function definitions: create-rocket-scene.v6
. The remaining constant definitions make the function
definitions readable and modifiable. As always, you can run this program
In comparison to the previous versions of create-rocket-scene,
this one shows that a program may consist of more than one function
definition that refer to each other. This revelation shouldn’t surprise
you. Even the first version of create-rocket-scene used
+ and / and other functions. It’s just that you think of
those as built into DrRacket.
As you become a true blue programmer you will find out that programs
consist of many function definitions and many constant definitions. You
will also see that functions refer to each other all the time. What you
really need to practice, is to create these definitions and organize them
so that you can read them easily, even months after completion. After all,
you or someone else will want to make changes to these programs, and if
you don’t know how to read them and if you didn’t organize them well, you
will have a difficult time with even the smallest task. Otherwise you
mostly know what there is to know and you can program.
You Are a Programmer Now
The claim that you are a programmer may have come as a surprise to you at
the end of the preceding section but it is true. You know all the
mechanics that there is to know. You know that programming—and
computing—is about arithmetic of numbers, strings, images, and whatever
other data your chosen programming languages support. You know that
programs consist of function and constant definitions. You know, because
we have told you, that in the end, it’s all about organizing these
definitions properly. Last but not least, you know that DrRacket and the
teachpacks support lots of other functions and that DrRacket HelpDesk explains
what these functions do.
You might think that you still don’t know enough to write programs that
react to keystrokes, mouse clicks, and so on. As it turns out, you do. In
addition to the animate function, the 2htdp/universe library
provide other functions that hook up your programs to the keyboard, the
mouse, the clock and other moving parts in your computer. Indeed, it even
supports writing programs that connect your computer with anybody else’s
computer around the world. So this isn’t really a problem.
In short, you have seen almost all the mechanics of putting together
programs. If you read up on all the functions that are available, you can
write programs that play interesting computer games, run simulations, or
keep track of business accounts. The question is whether this really means
you are a programmer.
Stop! Think! Don’t turn the page yet.
When you look at the “programming” book shelves in any random book store,
you will see loads of books that promise to turn you into a programmer in
21 days or faster. Some boast that you don’t need to know anything. Once
you have worked through the first part of this book, however, you know
that neither of these approaches can create a solid understanding of
Acquiring the mechanical skills of programming—learning how to write
instructions or expressions that the computer understands, getting to know
what functions are available in the libraries, and similar
activities—aren’t helping you much with real programming. To make
such claims is like saying that a 10-year old who knows how to dribble can
play on a professional soccer (football) team. It is also like claiming
that memorizing a thousand words from the dictionary and a few rules from
a grammar book teaches you a foreign language.
Proper programming is far more than the mechanics of acquiring a
language. It is about reading problem statements and extracting the
important concepts. It is about figuring out what is really wanted. It is
about exploring examples to strengthen your intuitive understanding of the
problem. It is about organizing knowledge, and it is about knowing what
you don’t know yet. It is about filling those last few gaps. It is about
making sure that you know how and why your code works, and it means
conveying this knowledge to all future readers of your code. In short,
proper programming is about solving problems systematically and conveying
the ideas within the code.
The rest of this book is all about these things; very little of the book’s
content is about the mechanics of DrRacket, BSL or libraries. The book
shows you how good computer programmers think about problems. And
promised, you will even learn to see that this way of solving problems
applies to other situations in life, e.g., the work of doctors and
journalists, lawyers and engineers, or car mechanics and photographers.
Oh, and by the way, the rest of the book uses a tone that is more
appropriate for a serious text than this prologue. Enjoy!
What the book is also not about Many introductory books on
programming contain a lot of material about the authors’ favorite
application discipline for programming: mathematics, physics, music, and
so on. To some extent including such material is natural, because
programming is obviously useful in those areas. Then again, this approach
distracts from proper programming and usually fails to tease apart the
incidental from the essential. In contrast, this book focuses on
programming and problem solving and what computer science can teach you in
this regard. We have made every attempt to minimize the use of knowledge
from other areas; for those few occasions when we went too far, we