Class summary: The Design Recipe
Copyright (c) 2017 Kathi Fisler
1 List versus link when writing functions that return lists
We developed a function that adds 1 to every element in a list of numbers.
fun add-1-all(lst :: List<Number>) -> List<Number>: |
cases (List) lst: |
| empty => empty |
| link(fst, rst) => link(fst + 1, add-1-all(rst)) |
end |
where: |
add-1-all([list: 3, 7, 4]) is link(3 + 1, add-1-all([list: 7, 4])) |
add-1-all([list: 7, 4]) is link(7 + 1, link(4 + 1, empty)) |
add-1-all(empty) |
end |
We went over why we had to write
| link(fst, rst) => link(fst + 1, add-1-add(rst)) |
instead of
| link(fst, rst) => [list: fst + 1, add-1-add(rst)] |
Roughly, using list: as in the second case makes a chain of nested lists, not a flat list.
We also talked about the importance of writing an example on the empty case so you can figure out what that case does before you are in the middle of writing code.
See the lecture capture video for more details.
2 A Systematic Process for Designing Programs
Let’s formally write out the sequence of steps that we’ve been informally using in class to design solutions to programming problems:
Write the name, inputs, input types, and output type for the function.
Write some examples of what the function should produce. The examples should cover all structural cases of the inputs (i.e., empty vs non-empty lists), as well as interesting scenarios within the problem.
Identify the tasks that the problem requires. Label each task with some information on how you will handle it (i.e., use a built-in function like L.filter, write a new function). If you are writing a new function, note the inputs and output for the task, along with the types.
For each task that requires you to write a function, start by copying the template for the main function input (i.e., the list template).
Fill in the templates and bodies for all task functions.
Combine the code for the tasks into code for the entire problem.
2.1 An example task list
Imagine that we asked you to write a program to compute the average number of vowels in a list of words. Here’s a possible task plan:
Define the set of vowels
Get a list of characters in a word [could use string-explode]
Count how many vowels are in a given word [could use L.filter, L.member, and L.length with the results from the previous two steps].
Sum the total number of vowels across all words in a list [could write a new function total-vowels that takes a list and returns a number].
Count the words in the list [could use L.length]
Compute the average number of vowels from the previous two values [using division].