Let's take a look at the definitions in figure
. The function
add-to-address-book consumes a symbol and a number. The former
represents a name, the latter a phone number. Its body contains a
set!-expression for address-book, a variable defined at
top-level. The function lookup consumes an address book
and a name; its result is the matching phone number or false, if
the name is not in address-book.
Using lookup, we can study the effect of the set! expression in add-to-address-book. Suppose we evaluate (lookup 'Adam address-book) with the given definitions:
(lookup 'Adam address-book)
= (lookup 'Adam empty)
= (cond
[(empty? empty) false]
[else ...])
= false
Because address-book is empty, we get false, and
the calculation is straightforward.
Now let's evaluate the following in the Interactions window:
(begin (add-to-address-book 'Adam 1)
(add-to-address-book 'Eve 2)
(add-to-address-book 'Chris 6145384))
The first subexpression is a plain function application. So, the first step
relies on the usual law of substitution:(define address-book empty)The next expression to be evaluated is the set!-expression that is nested in the begin-expressions, in particular its right-hand side. The first argument to cons is a value, but the second one is still a variable whose current value is empty. With this, we can see what happens next:(begin (set! address-book (cons (list 'Adam 1) address-book)) (add-to-address-book 'Eve 2) (add-to-address-book 'Chris 6145384))
(define address-book empty)(begin (set! address-book (cons (list 'Adam 1) empty)) (add-to-address-book 'Eve 2) (add-to-address-book 'Chris 6145384))
At this point we are ready to evaluate the set!-expression. Specifically, we change the definition of address-book so that the variable now stands for (cons (list 'Adam 1) empty):
(define address-book
(cons (list 'Adam 1)
empty))
(begin (void)
(add-to-address-book 'Eve 2)
(add-to-address-book 'Chris 6145384))
The begin-expression throws away the invisible value.
Evaluating the remaining applications of add-to-address-book yields
(define address-book
(list (list 'Chris 6145384)
(list 'Eve 2)
(list 'Adam 1)))
(void)
In short, the three applications turn address-book into a list of
three pairs.
If we now evaluate (lookup 'Adam address-book) in the Interactions window again, we get 1:
(lookup 'Adam address-book)
= (lookup 'Adam (list (list 'Chris 6145384)
(list 'Eve 2)
(list 'Adam 1))
= ...
= 1
The comparison of this evaluation and the one at the beginning of the
section shows how set! changes the meaning of
address-book over time and how the two functions,
add-to-address-book and lookup, implement the services
that we discussed in section
Exercise 35.4.1
The software for managing address books permits users to remove entries. Develop the function
;; remove : symbol -> void (define (remove name) ...)which changes address-book so that all future lookups for name yield false. Solution
Exercise 35.4.2
The teachpack phone-book.ss implements a graphical user interface
based on the model-view pattern discussed in
section
. Figure
shows what the graphical
user interface offers:
Use the teachpack's connect function to create a GUI for the
functions in this section and in exercise
.
The function has the following contract, purpose, and header:
;; model-T = (button% control-event% -> true) ;; connect : model-T model-T model-T -> true (define (connect lookup-cb change-cb remove-cb) ...)That is, it consumes three model functions and wires them up with the GUI. The names of the parameters specify which call-back function goes with which button.
A model function may obtain the contents of the name field with
(name-control) and the contents of the number field with
(number-field). Solution