A phone-list is either * empty * (cons pr pl) where pr : phone-record pl : phone-list (define-struct phone (name number)) A phone-record is (make-phone sym num).
Task: develop the following two functions
;; lookup : sym phone-list -> number ;; Purpose: produce the first number that is ;; associated with a-name in a-pl ;; in a phone-record (define (lookup a-name a-pl) ...) |
;; update : sym number phone-list -> phone-list ;; Purpose: produce a list like a-pl, but with the ;; first record for name replaced with ;; (make-phone a-name a-number) (define (update a-name a-number a-pl) ...) |
How do we "tell" lookup that update produced a new phone list?
![]() |
![]() |
The program underneath this GUI looks roughly like this:
(define PHONE-DB (list ...)) (define (lookup a-name a-pl) ...) (define (update a-name a-num a-pl) ...) ;; when someone looks up a phone number, call (lookup ...name from window... PHONE-DB) ;; when someone updates the phone list, what happens?
From the user's perspective, the program has "memory". But we know that
when we apply lookup to the same name and phone-list twice, we will always
get the same number -- no matter how often we have run update. What's up?
The key to "memory" is that we change what PHONE-DB stands for, i.e., to introduce some notion of time. Here is how that works:
(set! PHONE-DB (update ...name from UI... ...new number from UI... PHONE-DB))
Let's look at concrete examples:
(define PHONE-DB (list (make-phone 'Bumpy 5554567) (make-phone 'Mickey 6661234))) > (lookup 'Bumpy PHONE-DB) 5554567 > (lookup 'Bumpy PHONE-DB) 5554567 > (set! PHONE-DB (update 'Bumpy 3337654)) > (lookup 'Bumpy PHONE-DB) 3337654After a set! to PHONE-DB, the list that PHONE-DB stands for has changed.
Here is a program that can be associated with an update button on a GUI:
;; update! : sym number -> void ;; Effect: change what PHONE-DB stands for to (update a-name a-number PHONE-DB) (define (update! a-name a-number) (set! PHONE-DB (update a-name a-number PHONE-DB)))
Task:Define add!
;; add! : sym number -> void ;; Effect: adds a phone-record for a-name and a-number to PHONE-DB (define (add! a-name a-number) (set! PHONE-DB ...))
instead of modifying what a VARIABLE stands for, we can also change the contents of a record
(define a-rec (make-phone 'Bumpy 555666)) > (phone-number a-rec) 5556666 > (phone-number a-rec) 5556666 > (set-phone-number! a-rec 5557777) > (phone-number a-rec) 5557777
Some expressions have an effect only. Similar to routines that draw stuff on the screen. Since we might want to combine those in a sequence, e.g. do do do do, we introduce a new construct:
We can define programs now that modify the records on a list:
;; update! : symbol number phone-list -> void ;; Effect: modify the first record in phone-list ;; whose name is a-name so that it now contains ;; a-number (define (update! a-name a-number a-pl) (cond ((empty? a-pl) (void)) (else (cond ((eq? (phone-name (first a-pl)) a-name) (set-phone-number! (first a-pl) a-number)) (else (update! a-name a-number (rest a-pl))))))) |
;; update : symbol number phone-list -> phone-list ;; Purpose: produce a list like a-pl, but with the ;; first record for name replaced with ;; (make-phone a-name a-number) (define (update a-name a-number a-pl) (cond ((empty? a-pl) (void)) (else (cond ((eq? (phone-name (first a-pl)) a-name) (cons (make-phone (phone-name (first a-pl)) a-number) (rest a-pl))) (else (cons (first a-pl) (update a-name a-number (rest a-pl)))))))) |
Matthias Felleisen | This page was generated on Fri Apr 9 09:17:38 CDT 1999. |