550 likes | 692 Views
CS220 Programming Principles. 프로그래밍의 이해 2002 년 가을학기 Class 8 한 태숙. Strategies for Managing Data Complexity. Separate specification from implementation Procedural interface to data (enables alternative representations) Manifest typing (enables multiple representations)
E N D
CS220Programming Principles 프로그래밍의 이해 2002년 가을학기 Class 8 한 태숙
Strategies for Managing Data Complexity • Separate specification from implementation • Procedural interface to data (enables alternative representations) • Manifest typing (enables multiple representations) • Generic operations • Dispatch on type • Table-driven generic interface (Data-Directed Programming)
Packages • Closure • Coercion • Message-Passing
Rectangular and Polar Coordinates • Data-abstraction barriers in complex-number Programs that use complex numbers +c, -c, *c, /c Complex-arithmetic package Rectangular representation Polar representation List structure and primitive machine arithmetic
Selector and Constructor • Constructor (make-rectangle (real-part z) (imag-part z)) (make-polar (magnitude z) (angle z)) • Selector real-part, imag-part magnitude, angle
Complex Numbers - Operators • Complex Number Arithmetic (define (+c z1 z2) (make-rectangular (+ (real-part z1) (real-part z2)) (+ (imag-part z1) (imag-part z2)))) (define (-c z1 z2) (make-rectangular (- (real-part z1) (real-part z2)))) (- (imag-part z1) (imag-part z2)))) (define (*c z1 z2) (make-polar (* (magnitude z1) (magnitude z2)) (+ (angle z1) (angle z2)))) (define (/c z1 z2) (make-polar (/ (magnitude z1) (magnitude z2)) (- (angle z1) (angle z2))))
Dual Implementation(I) • Ben’s representation - rectangular coordinates (define (make-rectangular x y) (cons x y)) (define (real-part z) (car z)) (define (imag-part z) (cdr z)) (define (make-polar r a) (cons (* r (cos a)) (* r (sin a)))) (define (magnitude z) (sqrt (+ (square (car z))(square (cdr z))))) (define (angle z) (atan (cdr z) (car z)))
Dual Implementation(II) • Alyssa’s representation - Polar coordinates (define (make-rectangular x y) (cons (sqrt (+ (square x)(square y))) (atan y x))) (define (real-part z)(* (car z)(cos (cdr z)))) (define (imag-part z)(* (car z)(sin (cdr z)))) (define (make-polar r a) (cons r a)) (define (magnitude z) (car z)) (define (angle z) (cdr z))
Tagged Data • In order to support both types of complex numbers we need to be able to guarantee that, • selectors return appropriate values, independent of their implementation • We need TYPED data object, where the types can be seen by inspection. • Constructor - attach-tag • Selector - type-tag, contents • Predicate - is-the-type?
Type Tag - Implementation (define (attach-tag type-tag contents) (cons type-tag contents) (define (type-tag datum) (if (pair? datum) (car datum) (error “Bad datum --TYPE-TAG” datum))) (define (contents datum) (if (pair? datum) (cdr datum) (error “Bad datum --CONSTENS” datum)))
Complex Numbers - Rectangular? Polar? • Two types (representations) -rectangular and polar (define (rectangular? z) (eq? (type-tag z) ’rectangular)) (define (polar? z) (eq? (type-tag z) ’polar)) • We must add on a type tag whenever we construct complex numbers. • Since both representations coexist, we need to change the names of the procedures so as to avoid name conflicts.
Revised rectangular representation(I) ;Rectangular = ’rectangular x RepRect (define (make-from-real-imag-rectangular x y) (attach-tag ’rectangular (cons x y))) (define (make-from-mag-ang-rectangular r a) (attach-tag ’rectangular (cons (* r (cos a) (* r (sin a)))))
Revised rectangular representation(II) ; Rectangular -> Sch-Num (define (real-part-rectangular z) (car (contents z))) (define (imag-part-rectangular z) (cdr (contents z))) (define (magnitude-rectangular z) (sqrt (+ (square (real-part-rectangular z)) (square (imag-part-rectangular z))))) (define (angle-rectangular z) (atan (imag-part-rectangular z) (real-part-rectangular z)))
Revised polar representation(I) ;Polar = ’polar x RepPolar (define (make-from-mag-ang-polar r a) (attach-tag ’polar (cons r a))) (define (make-from-real-imag-polar x y) (attach-tag ’polar (cons (sqrt (+ (square x) (square y))) (atan y x))))
Revised polar representation(II) ; Polar -> Sch-Num (define (magnitude-polar z) (car (contents z))) (define (angle-polar z) (cdr (contents z))) (define (real-part-polar z) (* (magnitude-polar z)) (cos(angle-polar z)))) (define (imag-part-polar z) (* (magnitude-polar z) (sin(angle-polar z))))
Generic Operators and Constructors(I) ;; Complex = Rectangular U Polar ;; Selectors: Complex ->Sch-Num (define (real-part z) (cond ((rectangular? z) (real-part-rectangular z)) ((polar? z) (real-part-polar z)) (else (error “Unknown type-REAL-PART” z))))
Generic Operators and Constructors(II) ;; Complex = Rectangular U Polar ;; Selectors: Complex ->Sch-Num (define (imag-part z) (cond ((rectangular? z) (imag-part-rectangular z)) ((polar? z) (imag-part-polar z)) (else (error “Unknown type-IMAG-PART” z))))
Generic Operators and Constructors(III) ;; Complex = Rectangular U Polar ;; Selectors: Complex ->Sch-Num (define (magnitude z) (cond ((rectangular? z) (magnitude-rectangular z)) ((polar? z) (magnitude-polar z)) (else (error “Unknown type-MAGNITUDE” z))))
Generic Operators and Constructors(IV) ;; Complex = Rectangular U Polar ;; Selectors: Complex ->Sch-Num (define (angle z) (cond ((rectangular? z) (angle-rectangular z)) ((polar? z) (angle-polar z)) (else (error “Unknown type-ANGLE” z))))
Generic Operators and Constructors(V) ;; make-rectangular type Complex ;; Constructor: Sch-Num, Sch-Num -> Complex (define (make-rectangular x y) (make-from-real-imag-rectangular x y)) ;; make-polar type Complex ;; Constructor: Sch-Num, Sch-Num -> Complex (define (make-polar r a) (make-from-mag-angle-polar r a))
Generic Complex-Arithmetic System • Data-abstraction barriers in complex-number Programs that use complex numbers +c, -c, *c, /c Complex-arithmetic package real-part imag-part magnitude angle Rectangular representation Polar representation List structure and primitive machine arithmetic
Problems with this Approach • Generic Selectors depending on Type Tag • Dispatching on Type • Generic interface procedures must know about all the different representation. • need to add a clause for the new tag • No two procedures in the entire system have the same name. • can be programmed separately, but not independent • ==> Not Additive!
Data-Directed Programming • Table Driven Generic Interface Table of complex-number system Types Polar Rectangular real-part real-part-polar real-part-rectangular imag-part imag-part-polar imag-part-rectangular magnitude magnitude-polar magnitude-rectangular anlge angle-polar angle-rectangular Operations
Implementing Table Driven Operations • We need two table-manipulating operations and generic application of procedure. (put op type item) • installs the item in the table, indexed by the op and the type (get op type) • looks up the op, type entry in the table and returns the item found there. If no item is found, get returns false.
Ben’s Rectangular Package (p182) (define (install-rectangular-package) ;; internal procedures ;; RepRec = Sch-Num x Sch-Num (define (real-part z) (car z)) (define (imag-part z) (cdr z)) (define (make-from-real-imag x y)(cons x y)) (define (magnitude z) (sqrt (+ (square (real-part z)) (square (imag-part z))))) (define (angle z) (atan (imag-part z)(real-part z))) (define (make-from-mag-ang r a) (cons (* r (cos a)) (* r (sin a))))
;;interface to the rest of the system (define (tag x) (attach-tag ’rectangular x)) (put ’real-part ’(rectangular) real-part) (put ’imag-part ’(rectangular) imag-part) (put ’magnitude ’(rectangular) magnitude) (put ’angle ’(rectangular) angle) (put ’make-from-real-imag ’rectangular (lambda (x y) (tag (make-from-real-imag x y)))) (put ’make-from-mag-ang ’rectangular (lambda (r a) (tag (make-from-mag-ang r a)))) ’done)
Alyssa’s Polar Package (p183) (define (install-polar-packaage) ;; internal procedures (define (magnitude z) (car z)) (define (angle z) (cdr z)) (define (make-from-mag-ang r a)(cons r a)) (define (real-part z) (* (magnitude z) (cos (angle z)))) (define (imag-part z) (* (magnitude z) (sin (angle z)))) (define (make-from-real-imag x y) (cons (sqrt (+ (square x) (square y))) (atan y x)))
;;interface to the rest of the system (define (tag x) (attach-tag ’polar x)) (put ’real-part ’(polar) real-part) (put ’imag-part ’(polar) imag-part) (put ’magnitude ’(polar) magnitude) (put ’angle ’(polar) angle) (put ’make-from-real-imag ’polar (lambda (x y) (tag (make-from-real-imag x y)))) (put ’make-from-mag-ang ’polar (lambda (r a) (tag (make-from-mag-ang r a)))) ’done)
General “operation” procedure • Apply-generic • applies a generic operation to some argument • searches table with type and operation and applies the resulting procedure if one is present (define apply-generic op . args) (let ((type-tags (map type-tag args))) (let ((proc (get op type-tags))) (if proc (apply proc (map contents args)) (error “No method- apply”)))))
Generic Selectors Using Apply-generic (define (real-part z) (apply-generic ’real-part z)) (define (imag-part z) (apply-generic ’imag-part z)) (define (magnitude z) (apply-generic ’magnitude z)) (define (angle z) (apply-generic ’angle z))
Constructors Exported ; export constructor outside of the package (define (make-from-real-imag x y) ((get ’make-from-real-imag ’rectangular) x y)) (define (make-from-mag-ang r a) ((get ’make-from-mag-ang ’polar) r a))
Examples to be traced (define my-z (make-from-real-imag 3 4)) (real-part my-z)
Message passing • Decompose table into columns • Make object as dispatch procedures • dispatch on operation names by typed object • A data object receives the requested operation name as a “message.”
Message passing (Example) (define (make-from-real-immag x y) (define (dispatch op) (cond ((eq? op ’real-part) x) ((eq? op ’imag-part) y) ((eq? op ’magnitude) (sqrt (+ (square x)(square y)))) ((eq? op ’angle) (atan y x)) (else (error “Unknown Op” op)))) dispatch) (define (apply-generic op arg) (arg op))
System with Generic Operations Programs that use numbers add sub mul div Generic arithmetic package add-rat sub-rat mul-rat div-rat +c, -c, *c, /c + - * / Complex-arithmetic Ordinary arithmetic real-part imag-part magnitude angle Rational arithmetic Rectangular representation Polar representation List structure and primitive machine arithmetic
Adding Other kinds of Numbers • Ordinary numbers: (define (make-scheme-number n) (attach-tag ’scheme-number n)) (define (scheme-number? n) (eq? (type-tag n) ’scheme-number)) (define (add-scheme-number n1 n2) (make-scheme-number (+ n1 n2))) (define (sub-scheme-number n1 n2) (make-scheme-number (- n1 n2))) and ditto for mul div
Generic add using dispatch on type • complex, rationals, ordinary number (define add x y) (cond ((and (complex? x) (complex? y)) (add-generic-complex (contents x) (contents y))) ((and (rational? x) (rational? y)) (add-rat (contents x)(contents y)) ((and (scheme-number? x) (scheme-number? y)) (add-scheme-number (contents x) (contents y)))))
Generic Arithmetic Operation • add • add-rat on rational numbers • add-complex on complex numbers ..... (define (add x y) (apply-generic ’add x y)) (define (sub x y) (apply-generic ’sub x y)) (define (mul x y) (apply-generic ’mul x y)) (define (div x y) (apply-generic ’div x y))
Ordinary Numbers (p189) (defne (install-scheme-number-package) ;; Internal rep : RepNum = Sch-Num ;; internal procedures - just use scheme! ;; External rep: Scheme-Number = ;; ’scheme-number x RepNum (define (tag x) (attach-tag ’scheme-number x)) (put ’add ’(scheme-number scheme-number) (lambda (x y) (tag (+ x y)))) (put ’sub ’(scheme-number scheme-number) (lambda (x y) (tag (- x y)))) (put ’mul ’(scheme-number scheme-number) (lambda (x y) (tag (* x y))))
(put ’div ’(scheme-number scheme-number) (lambda (x y) (tag (/ x y)))) (put ’make ’scheme-number (lambda (x) (tag x))) ’done) ;; External constructor for ordinary numbers: ;; Sch-Num --> Number (define (make-scheme-number n) ((get ’make ’scheme-number) n))
Rational Number - generic number arith. (define (install-rational-package) ;;Internal rep: RepRat = Generic-Num x Generic-Num ;; internal procedure on RepRat (define (make-rat n d) (cons n d)) (define (numer x) (car x)) (define (denom x) (cdr x)) (define (add-rat x y) (make-rat (add (mul (numer x)(denom y)) (mul (denom x)(numer y))) (mul (denom x)(denom y)))) (define (sub-rat x y) (make-rat (sub (mul (numer x)(denom y)) (mul (denom x)(numer y))) (mul (denom x)(denom y))))
(define (mul-rat x y) (make-rat (mul (numer x)(numer y)) (mul (denom x)(denom y)))) (define (div-rat x y) (make-rat (mul (numer x)(denom y)) (mul (denom x)(numer y)))) ;; External rep: Rational = ’rational x RepRat (define (tag x) (attach-tag ’rational x)) (put ’make ’rational (lambda (n d) (tag (make-rat n d)))) (put ’add ’(rational rational) (lambda (x y) (tag (add-rat x y)))) (put ’sub ’(rational rational) (lambda (x y) (tag (sub-rat x y))))
(put ’mul ’(rational rational) (lambda (x y) (tag (mul-rat x y)))) (put ’div ’(rational rational) (lambda (x y) (tag (div-rat x y)))) ‘done) ;; External constructor interface (define (make-rational n d) ((get ’make ’rational) n d))
Complex Package (p191) (define (install-complex-package) ;; Internal Rep: RepComplex = Rectangular U Polar ;; import from rectangular and polar packaages (define (make-from-real-imag x y) ((get ’make-from-real-imag ’rectangular) x y)) (define (make-from-mag-ang r a) ((get ’make-from-mag-ang ’polar) r a)) ;; internal definitions .... (define (+c z1 z2) (make-from-real-imag (add (real-part z1)(real-part z2)) (add (imag-part z1)(imag-part z2))))
(define (-c z1 z2) (make-from-real-imag (sub (real-part z1)(real-part z2)) (sub (imag-part z1)(imag-part z2)))) (define (*c z1 z2) (make-from-mag-ang (mul (magnitude z1)(magnitude z2)) (add (angle z1)(angle z2)))) (define (/c z1 z2) (make-from-mag-ang (div (magnitude z1)(magnitude z2)) (sub (angle z1)(angle z2))))
;; interface to rest of system - export to table (define (tag z) (attach-tag ’complex)) (put ’add ’(complex complex) (lambda (z1 z2) (tag (+c z1 z2)))) (put ’sub ’(complex complex) (lambda (z1 z2) (tag (-c z1 z2)))) (put ’mul ’(complex complex) (lambda (z1 z2) (tag (*c z1 z2)))) (put ’div ’(complex complex) (lambda (z1 z2) (tag (/c z1 z2)))) (put ’make-from-real-imag ’compex (lambda (x y) (tag (make-from-real-imag x y)))) (put ’make-from-mag-ang ’compex (lambda (r a) (tag (make-from-mag-ang r a)))) ’done)
3+4i complex rectangular 3 4 ;; Exterrnal constructor interface (define (make-complex-from-real-imag x y) ((get ’make-from-real-imag ’compex) x y)) (define (make-complex-from-mag-ang r a) ((get ’make-from-mag-ang ’compex) r a))
Generic add using dispatch on type • complex, rationals, ordinary number (define add x y) (cond ((and (complex? x) (complex? y)) (add-generic-complex (contents x) (contents y))) ((and (rational? x) (rational? y)) (add-rat (contents x)(contents y)) ((and (scheme-number? x) (scheme-number? y)) (add-scheme-number (contents x) (contents y)))))
Generic Operation in Generic operation? • Generic call to ADD, MUL extend our system to deal with arbitrarily complex data types. (define (+c z1 z2) (make-from-real-imag (ADD (real-part z1)(real-part z2)) (ADD (imag-part z1)(imag-part z2)))) (define (add-rat x y) (make-rat (ADD (MUL (numer x) (denom y)) (MUL (numer y) (denom x))) (MUL (denom x) (denom y))))
Example to be traced (define 2+5i (make-complex-from-real-imag (make-scheme-number 2) (make-scheme-number 5))) (define 4+6i (make-complex-from-real-imag (make-scheme-number 4) (make-scheme-number 6))) (define 1+3i (make-complex-from-real-imag (make-scheme-number 1) (make-scheme-number 3))) (define 2+3i (make-complex-from-real-imag (make-scheme-number 2) (make-scheme-number 3))) (define 2+5i/4+6i (make-rational 2+5i 4+6i) (define 1+3i/2+3i (make-rational 1+3i 2+3i)