This guide is for anyone teaching COMP 50 at Tufts. If you are helping students, please follow the guidelines below.

I owe an immense debt to Matthias Felleisen—almost all of the questions are his.

Bedrock principles

How we interact with students

We don’t provide answers. Instead, we ask questions. We ask questions that are timeless and apply to many problems. Eventually, through force of repetition, the students learn to ask themselves the questions. At that point they can succeed even when we are not in the room.

What we are teaching and why

Good programmers proceed systematically. That’s what we’re here to teach.

Any programming language is an impediment to learning. We use the Beginning Student Language because it is less of an impediment than all the others. Why does the programming language matter?

The primary role of the programming language is to mitigate the consequences of mistakes. Thus, if a student complains that things would be easier if only the had objects, or Python, or copy constructors, or some other fashionable programming-language feature, we must remind them that expressive power is beside the point. The points are clarity and safety—first, the language shall do minimum harm.

How programs are designed

There is a distinction between designing programs and designing functions. In the first edition this distinction is not entirely clear. Here’s a sketch of how to design programs:

  1. Create a plan (which might spawn a wish list)

  2. Build the bricks needed to implement the plan (by designing functions)

  3. Compose the bricks to create the solution that was planned

    (Key step: identify the data used to communicate between “bricks”)

  4. Repeat and refine

How functions are designed

The key aspect of the design recipe is the six-step process:

  1. Analysis, data definitions, data examples

  2. Signature, purpose statement, and header

  3. Functional examples (containing calls to the function being designed)

  4. Code template(s) for the function body

  5. Code

  6. Tests

  7. (For generative recursion only) termination

We work with inductive data. This means any value that can be built in finitely many steps. From simpler to more complex, inductive data include

Each class of data comes with its own analysis, and each class determines a particular function template. If you’re going to learn to solve problems like a computer scientist, as opposed to a domain expert, you have to move beyond atomic data.

How to interact with students: The litany of questions

Traps and pitfalls for friendly teachers

Tufts culture is to be helpful. Our students want answers, and they think answers are helpful. Even better, the students reward us for answers. They smile at us, they are friendly, and they like us. Sadly, we’re not here to be liked—we’re here to help students learn. In particular, we’re here to help students master the design process. (Luckily, as you will know if you have taken COMP 40 or COMP 105, if we help the students learn a lot of good stuff, then when it’s over, they like us a lot. Successful students have used the design process in all sorts of situations—even to create poetry!)

Helping students learn means avoiding answers. Although providing answers gives everyone pleasure in the short term, we must deny ourselves these pleasures and instead ply the students with questions. Exercise constant vigilance!

Design recipe steps are covered in order

Systematic, step-by-step design is not fun until you start to master it. When they’re beginning, our students will be tempted to skip steps. To help our students resist temptation, we insist on seeing all the steps of the design recipe in order. We don’t help with step N + 1 until we have seen a reasonable attempt at step N.

0a. Fundamental skills and practices

Questions germane to the Bargain and the practice of being a successful student at Tufts:

0b. Interacting with DrRacket

These questions are based on some common mistakes or other unproductive behavior I have witnessed over the years.

1. Data analysis and description

What is the most challenging and creative part of our work as designers? Seeing data in the world and coming up with a precise description and definition of how the data will be represented in the computer. Many of our students may struggle here, and it may be difficult to get them to focus. But understanding the data is the key to everything that follows.

Questions to ask about data:

What constitutes a data definition? If you can build data, you have a definition.

2. Purpose statements and signatures

The purpose statement, signature,2 and function header all work together:

Some questions:

3. Functional examples

It’s so tempting to skip this step.

4. Function templates

Once we have a signature and all the data definitions, creating the function template should be completely mechanical.3 But there are a lot of details to manage, and we should expect students to need help.

5. Coding

This is another step that requires some creativity, but it is more of the puzzle-solving variety. Coding obviously builds on the function template, but it is also helpful to use the tables of examples from step 3, and the whole effort must be guided by signatures and purpose statements from step 2.

6. Testing

Our students should use check-expect and check-within early and often.

Questions to ask when tests don’t pass:

7. Termination

Applies only to generative recursion. Coming later.


  1. Atomic data, definition by parts (structure), and definition by choice (variants). There is a fourth: definition by self-reference.

  2. In the first edition, a signature is (mistakenly) called a “contract.”

  3. If you like math, data definitions and function templates are related by a homomorphism. Actually even if you don’t like math, they are still related by a homomorphism.