[previous] [up] [next]     [index]
Next: Designing Functions with Memory Up: Assignment to Variables Previous: Assignments and Functions

A First Useful Example

Let's take a look at the definitions in figure [cross-reference]. 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 variable. 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.


 
(define address-book empty)

;; add-to-address-book : symbol number -> void (define (add-to-address-book name phone) (set! address-book (cons (list name phone) address-book)))

;; lookup : symbol (listof (list symbol number)) -> number or false
;; to lookup the phone number for name in ab 
(define (lookup name ab) 
  (cond 
    [(empty? ab) false] 
    [else (cond 
            [(symbol=? (first (first ab)) name) 
             (second (first ab))] 
            [else (lookup name (rest ab))])])) 

Figure: The basic address-book program


Using lookup, we can study the effect of the set! expression in add-to-address-book. Supposed 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:[footnote]
 
(define address-book empty)

(begin (set! address-book (cons (list 'Adam 1) address-book)) (add-to-address-book 'Eve 2) (add-to-address-book 'Chris 6145384))

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:
 
(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 [cross-reference]. The exercises show how useful this collaboration of two functions is in the context of a graphical user interface.


Exercises

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 falseSolution

Exercise 35.4.2

The teachpack phone-book.ss implements a graphical user interface based on the model-view pattern discussed in section [cross-reference]. Figure [cross-reference] shows what the graphical user interface offers:

  1. a text-field for entering a name;
  2. a text-field for displaying the search result and for entering a phone number;
  3. a button for looking up the phone number for a name;
  4. a button for adding a name and a phone number; and
  5. a button for removing the phone number for a name.

Use the teachpack's connect function to create a GUI for the functions in this section and in exercise [cross-reference]. 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



[previous] [up] [next]     [index]
Next: Designing Functions with Memory Up: Assignment to Variables Previous: Assignments and Functions

PLT