Box-and-Pointer Representation: As we have often seen, Scheme uses
cons to build lists. We now consider a graphical way to represent
the result of a cons procedure. The basic idea is to use a
rectangle - divided in half - to represent the result of the cons.
From the first half of the rectangle, we draw an arrow to the head of a
list; from the second half of the rectangle, we draw an arrow to the rest
of the list. For example, (cons 'a '()) would be represented as
follows:
Here, the line to a indicates that this is the head of the list.
The diagonal line through the right half of the rectangle indicates that
nothing comes later in this list. Since (cons 'a '()) gives
the list (a), this diagram represents (a) as well.
Now consider the list (cons 'b '(a)) or (b a). Here, we
draw another rectangle, where the head points to b and the tail
points to the representation of (a) that we already have seen.
The result is:
Similarly, the list (d c b a) is constructed as
(cons 'd (cons 'c (cons 'b (cons 'a '())))) and would be drawn as
follows:
A similar approach may be used for lists, which have components which
are sublists. For example, consider the list ((a) b (c d) e)
This is a list with four components, so at the top level we will need
four rectangles, just as in the previous example for the list (d c b
a). Here, however, the first component designates the list
(a), which itself involves the box-and-pointer diagram already
discussed. Similarly, the list (c d) has two boxes for its two
components (just as we discussed for (b a) earlier). The
resulting diagram follows:
Additional discussion and examples may be found in the first few pages of
Section 11.3 in the textbook.
Throughout these diagrams, the null list is represented by a null pointer
or line. Thus, the list containing the null list, ( ( ) ) - that
is (cons '() '()) - is represented by a rectangle with lines
through both halves:
((x) y z) (x (y z)) ((a) b (c ()))
(cons 'a "Walker") (cons 'a '()) (cons '() 'a) (cons '() '())
One way to write such a directory in Scheme is to consider each entry as a two-element list, such as ("walker" 4208) or ("stone" 3181). An entire directory, then, could be considered as a list of such entries:
( ("herman" 4202) ("stone" 3181) ("walker" 4208) )
In Scheme, such a list of pairs is called an association list or
alist.As the telephone directory example illustrates, a particularly common application of association lists involves looking for a desired name or first element of a pair and retrieving the second element of a pair. Thus, the first element of each pair (the car of a pair) often is called a key value, and the remainder of the pair is its associated data. For example, in the above illustration, "herman", "stone", "walker" are the keys, and the numbers are the associated data. As this example suggests, association lists are a simple way to implement small databases.
Since such applications are so common, Scheme provides procedures to retrieve a pair containing a desired key. The most frequently used such procedure is assoc. Given a key and association list, assoc returns the first pair with the given key. If the key does not match any key, then assoc returns false (#f). For example,
(assoc "stone" '(("herman" 4202) ("stone" 3181) ("walker" 4208)))
returns ("stone" 3181), while .
(assoc "jepsen" '(("herman" 4202) ("stone" 3181) ("walker" 4208)))
returns #f. Since such directories typically contain several entries, this is a particularly good circumstance to use a define expression, so a symbol can represent the entire directory:
(define telephone-directory
'( ("herman" 4202)
("stone" 3181)
("walker" 4208)
)
)
With such a definition, (assoc "stone" telephone-directory)
returns ("stone" 3181), and (assoc "jepsen"
telephone-directory) returns #f.To find the telephone number corresponding to a given name, we could apply the cadr procedure to the result of assoc:
(cadr (assoc "stone" telephone-directory))returns 3181.
(assq 'a '((a 1) (b 2) (c 3))) (assq 'b '((a 1) (b 2) (c 3))) (assq 'd '((a 1) (b 2) (c 3))) (assq (list 'a) '(((a) q) ((b) (r)) ((c)))) (assoc (list 'a) '(((a) q) ((b) (r)) ((c)))) (assoc (list 'c) '(((a) q) ((b) (r)) ((c))))In each case, be sure you can explain why the result is obtained.
This document is available on the World Wide Web as
http://www.math.grin.edu/~walker/courses/151.sp99/lab-pairs.html