meeting -*- Outline -*- * data abstraction (2.1) raise your hand if you aren't familiar with ADTs? ** terminology ------------------------------------------ DATA ABSTRACTION terms: data abstraction, ADT example: nonnegative integers divide program into 2 parts 1. knows about representation (the ADT implementation) 2. doesn't know details of representation (the client) def: a program exhibits if it works correctly with any correct implementation of an ADT. example: ------------------------------------------ ...representation independence ... most programs are independent of the rep for numbers, lists, we'll also be independent of the rep of records. Q: Are C programs independent of the representation of numbers? Q: What good is this? it allows you to change the representation by only changing small number of procedures ** opaque vs. transparent implementations ------------------------------------------ OPAQUE VS. TRANSPARENT REPS > (require (lib "sym-cell-mod.scm" "lib342")) > (define my-cell (sym-cell 'foo)) > (cell-ref my-cell) foo > (vector? my-cell) > my-cell def: a type is *opaque* if otherwise it is transparent. ------------------------------------------ ... #t, #(342) ... there is no way to find out its rep, even by printing Q: which kind does Scheme have? C++? Smalltalk has opaque Q: What's the advantage of an opaque type? of transparent? opaque enforces use of the defining procedures, has better security transparent is easier to debug and extend (which is also a disadvantage!) ** type checking and ADTs The following is adapted from Figure 4.5.1 : page 125, of EOPL first edition ------------------------------------------ TYPE CHECKING AND ADTS ;;; Adapted from Figure 4.5.1 (module sym-cell-mod (lib "typedscm.ss" "typedscm") (provide sym-cell sym-cell-ref sym-cell-set!) ;; constructor (deftype sym-cell (-> (symbol) sym-cell)) ;; observer (deftype sym-cell-ref (-> (sym-cell) symbol)) ;; mutator (deftype sym-cell-set! (-> (sym-cell symbol) void)) (defrep (sym-cell (vector-of symbol))) (define sym-cell-tag 'sym-cell-tag) (define sym-cell (lambda (x) ;; ENSURES: result is a new sym-cell containing x (vector sym-cell-tag x))) (define sym-cell? (lambda (x) (has-type-trusted boolean (and (vector? x) (= (vector-length x) 2) (equal? (vector-ref x 0) sym-cell-tag))))) (define sym-cell-ref (lambda (x) ;; ENSURES: result is the contents of x (if (sym-cell? x) (vector-ref x 1) (error "Invalid argument to sym-cell-ref: " x)))) (define sym-cell-set! (lambda (x value) (if (sym-cell? x) (vector-set! x 1 value) (error "Illegal argument to sym-cell-set!: " x)))) ) ;; end module ------------------------------------------ Q: What are the types of these procedures internally? (deftype sym-cell (-> (symbol) sym-cell)) vs. (deftype sym-cell (-> (symbol) (vector-of symbol))) (deftype sym-cell-ref (-> (sym-cell) symbol)) vs. (deftype sym-cell-ref (-> ((vector-of symbol)) symbol)) etc. ------------------------------------------ ABSTRACTION MAPPING ( sym-cell ) abstract type ^ | | /-------------------/ / (vector-of datum) / rep type /-------------------/ ------------------------------------------