Page 3: Even Numbers and Keep

Unit 8, Lab 4, Page 3

On this page, you will build two other higher order functions you’ve learned in this course: keep and combine.

We want a block that takes a list of numbers as input, and reports a list of just the even numbers from the input.

You already know how to write this block using the keep higher-order function, but here’s what it looks like using recursion:
evens (numbers){if(empty? (numbers)){return(empty list)} else{if((item(1) of (numbers)) mod (2)=0){report(item(1) of (numbers) in front of (evens (all but first of (numbers))))} else{report(evens(all but first of (numbers)))}}}

Here there are threepossible cases to consider, not just the usual base case and recursive case. There’s still a base case, namely an empty input list, in which case we report an empty list. But there are tworecursive cases, depending on whether or not the first item of the list is even. (There has to be a first item, if we’re not in the base case.) The green Operators blocks above take the remainder on dividing the first number by 2, and see if that remainder is 0, in which case the number is even.

If the first number is even, then we want to include that number in the result. So we report that number in front of the recursive call on the rest of the numbers. If the first number isn’t even, then we don’twant to include it in the result, so we simply report the value reported by the recursive call.

Like plurals, the evens code is an example of a pattern of code. There’s nothing special about even numbers here. The same pattern could be used to make a list of odd numbers, or numbers that end in 7, or names that start with a Z.

Do the following exercises using recursion, not higher order functions.

  1. Try modifying the code from evens.

    Write a block ends-e that takes a list of words as input, and reports a list of those words from the input whose last letter is e.
    ends-e(list{the, rain, in, Spain, is, in, Europe}), reporting {the, Europe}

  1. Write a block numbers that takes a list of mixed words and numbers as input, and reports a list of just the numbers from the input list.
    numbers(list{the, 1, after, 909}), reporting {1, 909}

  1. Generalize the pattern to make a keep block.

  1. Write the combine block. Note: The base case will be a list with one item, not an empty list.

Building map, keep, and combine is a major accomplishment. You’ve built a real gem of abstraction: higher-order functions, which treat a list as a single value. Some people don’t even learn to use higher-order functions in college, let alone build them. 🎉 Congratulations! 👏 You’ve finished BJC! 🏆

Take It Further…
  1. Do Unit 8 Lab 6: Sorting (Optional).

  1. Modify any of the sorting algorithms you built in the Sorting lab to take a comparison predicate as an input, so you can say
    sort(some-values) using (()>()) to compare
    to sort with the largest item coming first.