The design recipe is here to help you design programs properly. When beginning to solve a new problem, the first question to ask yourself is: do I need a new type of data? If so, follow the steps in the Data column for every new type of data you need. When writing functions, follow the steps in the Function column for every function you write.
Note that "do I need a new type of data?" can often be answered with the question "can I write the signature of the function I want to write?"
Below are helpful questions to ask yourself when tackling a specific step of the data design recipe:
What do I need to keep track of?
How many cases are there?
In each case, do I need to keep track of more than one thing? (if so, I need a struct or list)
In each case, how do I encapsulate what I need to keep track of? (number? some other struct? list? etc.)
What about this data is potentially unclear/needs to be explained?
Are there units? (grid vs. pixel, for example)
Have I covered every case of the data definition?
Do I have relevant examples for testing for the functions I know I need?
How many cases of the data are there?
How do I tell them apart?
What data can I pull out at the top level of those cases?
Are the pieces of data I can pull out complex with their own template that I should call to (possibly self referential)?
Below are helpful questions to ask yourself when tackling a specific step of the function design recipe:
What pieces of data does this function need to take in?
What are their types?
What does this function output and what is its type?
What is this function doing?
Have I covered every case?
Have I covered edge cases?
Do the tests I have convince me my function is properly written?
Can what I’m trying to achieve be broken down into multiple steps (i.e. should I use helpers)?
What template do I use?
As you may have noticed, the layout of the design recipe above (in table format) is different than what is found in the textbook.
Express how you wish to represent information as data.
Write down a signature, a statement of purpose, and a function header.
Illustrate the signature and the purpose statement with some functional examples.
Replace the function’s body with a template.
Test your code.
However, we feel the tabular display of the design recipe is somewhat clearer, as it breaks out which steps are related to data design and which steps are related to functions.
The representation seen above is derived from textbook representation as follows: Step 1, in regards to representing data, becomes the data definition and interpretation. Step 2 becomes the signature and purpose statement. Steps 3 and 6 become the tests, and step 3 also becomes examples. Step 4 is now the template step. Step 5 is now the code step.
The list as given in the book interweaves both data design and function design, and having the two displayed separately shows that they can be done independently of each other. It also makes it clear that templates and examples need to be written once for each data definition, as opposed to for each function, and that every function should have a signature, purpose statement, and tests.
Data definitions and signatures both specify types of data.
Interpetations and purpose statements both clarify the intent of code in English.
Examples drive tests.
Templates drive code.