Recall the plane structure we used on Friday.  A plane contained its
brand, how many miles it flew since servicing, and the name of the
mechanic who last serviced it.  The airline wants to keep more
detailed servicing records and decides to record the last three
mechanics who serviced the plane.  How would we do that?

	(define-struct 3mechs (recent two-ago three-ago))

How would we record that the last three mechanics to service a plane
were Mike, Patty, and Bubba?

	(make-3mechs 'Mike 'Patty 'Bubba)

Write a program Bubba-serve? which takes a 3mechs structure and
returns true if Bubba has serviced the plane, false otherwise.

Our contract, purpose, and template:

;; Bubba-serve? : 3mechs -> bool
;; determine whether Bubba is one of the 3 mechanics
(define (Bubba-serve? a-3mech)
  ...(3mechs-recent a-3mechs)...
  ...(3mechs-two-ago a-3mechs)...
  ...(3mechs-three-ago a-3mechs)...)

Fill in the template for the answer

;; Bubba-serve? : 3mechs -> bool
;; determine whether Bubba is one of the 3 mechanics
(define (Bubba-serve? a-3mech)
  (or (symbol=? 'Bubba (3mechs-recent a-3mechs))
      (symbol=? 'Bubba (3mechs-two-ago a-3mechs))		
      (symbol=? 'Bubba (3mechs-three-ago a-3mechs))))

What if the airline wanted to track all mechanics who had ever
serviced a plane, not just the last three?  What struct would you
define?  The problem is that define-struct fixes the number of items
that you glue together.  However, we don't know how many mechanics
will service a plane, so we can't define the structure.

We need a way to glue together arbitrarily many names of mechanics.
What do you do when you want to keep track of many pieces of
information?  You make a list.  Let's write down the mechanics who
last serviced a particular plane:

Eddie
Mike 
Patty
Bubba

We need a way to turn this list into data for DrScheme.  Let's start
simple.  What's the smallest list you can think of?  Empty list.  In
Scheme, we write empty for the empty list.  Now, we need a way to
create non-empty lists.

Let's look at the list on the board.  We agree that what's there is a
list.  Is

Mike
Patty
Bubba

a list?  What's the relationship between these two lists?  The first
has added a name onto the second.  Therefore, we can think of a list
as having two parts: the name at the top and the rest of the list.
Can you define a struct to capture these two pieces of information?

	(define-struct lst (first rest))

Using this struct, how would you create a list containing Bubba?

	(make-lst 'Bubba empty)

Before we continue, let's write down the data definition for a list of
symbols.

;; A list-of-symbols is either
;;	- empty, or
;;	- (make-lst name a-los)
;;	  where name is a symbol and a-los is a list-of-symbols

How would you define the list containing Mike, Patty, and Bubba?

  (make-lst 'Mike 
            (make-lst 'Patty 
	              (make-lst 'Bubba
		                empty)))

How would you get Mike out of this list?

  (lst-first (make-lst 'Mike 
		       (make-lst 'Patty 
			         (make-lst 'Bubba
				           empty))))

How would get Patty out of this list?

  (lst-first (lst-rest (make-lst 'Mike 
		                 (make-lst 'Patty 
				           (make-lst 'Bubba
					             empty)))))

Let's re-write our earlier program Bubba-serve? to consume a list of
symbols rather than a 3mechs structure.

;; Bubba-serve? : list-of-symbols -> bool
;; determine whether Bubba is a mechanic in the list
(define (Bubba-serve? a-los) ...)

What about the template?  How many cases in the data definition?  Two,
so we need a cond with two branches:

;; Bubba-serve? : list-of-symbols -> bool
;; determine whether Bubba is a mechanic in the list
(define (Bubba-serve? a-los)
  (cond [... ...]
        [... ...]))

What question do we ask to detect the empty case? Scheme provides the
operator empty?.  So our template looks as follows:

;; Bubba-serve? : list-of-symbols -> bool
;; determine whether Bubba is a mechanic in the list
(define (Bubba-serve? a-los)
  (cond [(empty? a-los) ...]
        [(lst? a-los) ...(lst-first a-los)...(lst-rest a-los)...]))

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 a-los is a list-of-symbols?  The
definition itself is called 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
a-los)?  Just that it is a symbol, so we don't have to do anything
else with it.  What about (rest a-los)?  Well, we know that it is a
list-of-symbols.  Do we have a way to check whether Bubba is in a list
of symbols?  Yes, using Bubba-serve?  So, we can draw an arrow from
(rest a-los) back to Bubba-serve?.  What do you notice about this
arrow?  It looks just like the arrow in the data definition!

We want to include the arrow in our template.  The arrow tells us to
use Bubba-serve? to process lists of symbols.  Since we can't type the
arrow into DrScheme, we'll do the next best thing: call the program
Bubba-serve? on (rest a-los) in the template.

;; Bubba-serve? : list-of-symbols -> bool
;; determine whether Bubba is a mechanic in the list
(define (Bubba-serve? a-los)
  (cond [(empty? a-los) ...]
        [(lst? a-los) ...(lst-first a-los)
	              ...(Bubba-serve? (lst-rest a-los))...]))