Examples with Lists

We saw a data definition last time:

;; A List-of-Symbols is either
;;	- empty, or
;;	- (cons symbol List-of-Symbols)

;; Examples of data:

empty

(cons 'Bubba empty)

(define mpb (cons 'Mike (cons 'Patty (cons 'Bubba empty))))
Note that this form of data definition isn't anything new; we're going to just follow the same template as ever. The twist, to get our mind around, is that the type of one of the struct's fields is itself a complicated type. (Actually, we'd seen that, too...?)

Okay, let's try writing functions! Write a program times-served to consume a list of symbols rather than a limited 3mechs structure.

;; times-served : list-of-symbols -> number
;; Determine the length of the list of mechanics' names.
;;
(define (times-served mechs) ...)

; Test cases for function:
(times-served empty) = ..

(times-served (cons 'Bubba empty)) = ..

(times-served mpb) = 

What about the template? How many cases in the data definition? Two, so we need a cond with two branches:
;; times-served : list-of-symbols -> number
;; Determine the length of the list of mechanics' names.
;;
(define (times-served mechs)
  (cond [... ...]
        [... ...]))
What question do we ask to detect the empty case? Scheme provides the operator empty?. So our template looks as follows:
;; times-served : list-of-symbols -> number
;; Determine the length of the list of mechanics' names.
;;
(define (times-served mechs)
  (cond [(empty? mechs) ...]
        [(cons?  mechs) ..(first mechs)..(rest mechs)..]))

Have we exploited all of the information in the data definition? Almost. There's one piece of information there that we overlooked. Notice how the definition says that the second part of the make-cons is a List-of-Symbols? We want to record this relationship in the data definition itself. We do this by drawing an arrow from the second occurrence to the original definition.

Now, return to the template. Do we know anything else about (first mechs)? Just that it is a symbol, so we don't have to do anything else with it. What about (rest mechs))? Well, we know that it is a List-of-Symbols. Do we have a way to calculate the length of this sublist? So, we can draw an arrow from (rest mechs)) back to times-served. What do you notice about this arrow? It looks just like the arrow in the data definition! The shape of the data is being reflected in the shape of the program which handles that data.

We want to include the arrow in our template. The arrow tells us to use times-served. to process lists of symbols. Since we can't type the arrow into DrScheme, we'll do the next best thing: call the program times-served (which wants to consume List-of-Symbols), on the input (rest mechs) (which, happily, is indeed a List-of-Symbols).

;; times-served : List-of-Symbols -> number
;; Determine the length of the list of mechanics' names.
;;
(define (times-served mechs)
  (cond [(empty? mechs) ...]
        [(cons?  mechs) ..(first mechs)..(times-served (rest mechs))..]))
Let's now fill in the body. We'll have an in-class live demo, working through the function.
to do on your own: Work through this function with the stepper, to internalize how the recursive calls work.

Exercise, with a neighbor: Write the function contains-bubba? : List-of-Symbols --> boolean. You already have the template for a List-of-Symbols, right?

In lab this week, you'll see this same idea revisited repeatedly. The twists:

An English aside: "To recur" is what programs do; "to recurse" is what you may sometimes do in frustration.