CSC151.01 2006S, Class 47: Object Basics Adim: * Due: HW16. * Exam 3 will be distributed tomorrow. * Reading for tomorrow: Reread objects * Computing a simple sum Overview: * Representing Compound Values. * Introduction to Objects. * Procedures as Objects. * Adding State. /HW16/ * When the input size doubles, what happens to the number of steps? * Individual numbers can be misleading. * Suppose algorithm A takes (on average) 1,000 steps for an input of size 1000. * Suppose algorithm B takes (on average) 10,000 steps for an input of size 1000. * Suppose when we double the size of the input, the cost of algorithm A quadruples and the cost of algorithm B doubles. * Which algorithm would you use on a list of 128,000 values? /What is the following sum?/ * 1 + 2 + 3 + .... + 100 (5050) or * 1 + 2 + 3 + .... + n * = n(n+1)/2 [analysis on real whiteboard] * And Sam made fun of famous mathematicians who he clearly envies. /Goals of Software Engineering/ * When you build a compound value: * The user of that compound value need not understand the structure. * Library books * Author: String * Title: String * Publisher: String * ISBN13: String * Library of Congress #: String * Year: String (so that we support clear values that only Zack can read, like MCMXIII) * And then * Shove 'em in a vector (vector "Samuel A. Rebelsky" "Experiments in Java" "Addison-Wesley Longman" "IHAVENOFREAKINGIDEA" "QA76.123 R1" "1999") * Shove 'em in a list (list "Samuel A. Rebelsky" "Experiments in Java" "Addison-Wesley Longman" "IHAVENOFREAKINGIDEA" "QA76.123 R1" "1999") * Store 'em in a file (display "Samuel A. Rebelsky" sams-books) (display "Experiments in Java" sams-books) * Or, Store 'em in a file with field names (display "Author: Samuel A. Rebelsky" sams-books) (display "Title: Experiments in Java" sams-books) * Or, Store 'em in an association list (list (cons 'author "Samuel A. Rebelsky") (cons 'title "Experiments in Java") ...) * Association lists are nice because they make it easier to search. * Someone wants to use our book representation * Do we teach them the representation? * Do we give them procedures that access the representation?a (make-book author title ...) (get-book-title book) (set-book-title! book newtitle) ... * Procedures are better because * They limit what the programmer can do (e.g., they can't do "inappropriate" things). * Easier to teach. * Just easier. * Saves client programmer effort. * Easier to change the representation But ... in Scheme (at least), the client can figure out the representation. > (define samsbook (make-book "Samuel A. Rebelsky" "How Not To Teach Software Engineering" ...)) > samsbook * #6("Samuel A. Rebelsky" ...) ; vector * ("Samuel A. Rebelsky" ...) ; list * (('author "Samuel A. Rebelsky") ...) ; association list Assume an association list > (define samsbook (cons (list 'author "SamR") samsbook)) * Good: Client can do whatever she wants. * Bad: Client can do things that violate expectations. > (define samsbook (cons (list 'author 23) samsbook)) Can we prevent the client from doing this? (That is, doing "unauthorized things" to a compound value.) * In some languages, there's a way to build restricted compound values: Objects * Invented in late 1960's in Norway (or some similar country) * Nygaard and Dahl * One reason: Restrict access * Another reason: Modeling In Scheme, we need a way to build our own objects. Hiding representations is somewhat hard. Except! We know how to build values local to a procedure. (define silly (let ((name "Sam")) (lambda () name))) vs. (define name "Sam") (define yllis (lambda () name)) (define valid-symbolic-grades (list 'plus 'check-plus 'check 'check-minus 'minus 'zero)) (define valid-homework-grade? (lambda (grade) (member grade valid-symbolic-grades))) ... (define valid-symbolic-grades (list 'A+ 'A 'A- 'B+ ... )) (define valid-symbolic-grades (define valid-homework-grade? (let ((valid-symbolic-grades (list 'plus 'check-plus 'check 'check-minus 'minus 'zero))) (lambda (grade) (member grade valid-symbolic-grades)))) This strategy also works for limiting the kinds of things we want to do. Objects will be procedures that take "what should I do to this object?" as a parameter. (define numeric-grade (let ((grade (vector 0))) (lambda (command . params) (cond ((eq? command ':addto) (if (not (number? (car params))) (error "Can only add numbers to grades") (vector-set grade 0 (+ (vector-ref grade 0) (car params)))))))))