This blog is a comprehensive study guide distilled from many past exams (2019–2024) and lecture rules in HTDP / Racket. It focuses on evaluation, function design, data-driven templates, recursion, abstraction, local/closure, and common exam traps.
Author’s note:
This blog was summarized from the everyday notes and mistake summary by the author while revising for exams. Its sole purpose is to help write clear, readable, and collaboration-friendly code, and to understand the underlying execution model of Racket programs. It does not cover the three algorithm-focused chapters (for example, graphs, accumulators, and search).
For those algorithmic chapters, the most important advice is: go through past papers by yourself. Separate blog posts will be written later to specifically cover the algorithmic content in HTDP.
Evaluation Questions (Step-by-Step Reduction)
Core Rules
- Substitute all parameters at once.
- Substitute constants defined by define one by one, in order.
- For cond, reduce the condition first, then evaluate the chosen branch.
- For or, the first true stops evaluation.
Always run the program to confirm the final value.
Function Debugging Questions
Common Fixes
a. Predicate functions must end with ?
b. check-expect needs enough variance (larger, smaller, and same cases)
c. String stubs usually return an empty string, not false
d. (number? x) already returns a Boolean, so do not wrap it with if
e. If you test button-down, also test button-up
f. Run first, read the error message, then inspect the function body
Frequent Bugs
a. Swapped coordinates in selectors
b. Using the wrong selector (x vs y)
c. Stub does not match the function signature
HTDD (How to Design Data)
Rules
a. The last condition in cond should use else
b. If the data is self-referential, the template must recurse
HTDW (World Programs)
Key Events
Handle key events using a cond on the key value, with a final else case that returns the unchanged world.
Tips
a. The render function must be defined before big-bang
b. Keep false handling consistent across event handlers
Reference and Recursion Questions
Self vs Mutual Reference
a. Self-recursive: a function calls itself
b. Mutual-recursive: functions call each other
Trust Natural Recursion
Once the first element is correct, trust the rest.
Do not repeatedly re-check (first (rest ...)).
Empty Base Cases (VERY IMPORTANT)
sum of an empty list returns 0
product of an empty list returns 1
append with an empty list returns empty
Abstraction and Higher-Order Functions
Choosing the Right Abstract Function
- Use map or filter when the goal is to produce a list
- Use foldr or foldl when the goal is to aggregate values
- Use build-list when generating a list based on indices
Function Signatures
- map: takes a function from X to Y
- filter: takes a function from X to Boolean
- foldr: takes a function from X and Y to Y
- build-list: takes a Natural number to X
Common Error
Do not call a function when passing it as an argument.
Pass the function name itself.
Local, Closure, and Lifting
Closure Definition
A function is a closure if:
- It is a function
- It uses variables not listed in its parameters
- Those variables come from an outer scope
Evaluation Cost
- Definitions outside loops are evaluated once
- Definitions inside loops are evaluated on every iteration
Genrec (Generative Recursion)
Must Include
- A base case
- A reduction step
- A termination argument
Common Mistake
A wrong base case leads to incorrect images or values.
Well-Formed Data Definitions
Not well-formed:
A data definition that directly contains itself with no base case.
Well-formed:
A data definition that includes a base case and a recursive reference.
Helper Functions — When Are They Needed?
Use a helper function when:
- Referencing non-primitive nested data
- Performing two-phase processing
- Switching knowledge domains
- Handling arbitrary-sized data such as lists or trees
Parameters vs Arguments vs Operands
Parameter: a name in a function definition
Argument: a value passed to a function call
Operand: an input to an operator
Exam Survival Checklist
Follow the template strictly
Match signature letters exactly
Always consider the case where rest is empty
Order cond clauses carefully
Only write function names in function positions
Do not call functions when passing them as arguments
Always run the code
Final Advice
Design correctly, then trust recursion.
HTDP exams reward discipline, templates, and precision, not clever hacks. I personally feel very rewarded as a beginner through learning these basic design principles and extending them in future programming as a behaved and cooperative programmer.
Top comments (0)