* Lecture 2B Compound Data https://youtu.be/DrFkf-T-6Co so far we've been talking about procedures - primitive things - means of combination - means of abstraction we've seen general methods for computing things the Crucial idea: !! We are building a layered system abstraction boundaries, ie : sqrt ;; above the abstraction layer : /---------------\ ;; abstraction layer : good-enuf? ;; hidden parts divorce the task of building things from the task of building their parts. now we will look at the same thing in terms of data - primitive data - glue for combining - methodology for abstraction all of which we will do by building layers of abstraction. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' the system we will be considering is rational numbers: how to add, mul, sub, div fractions we dont /have/ a system for rational numbers scheme gives us a system for numbers, but not a number for a numerator and a denominator we will enable this by using the technique of !! WISHFUL THINKING we will imagine we have these procedures : (make-rat n d) ;; -----> returns some 'cloud' containing n and d : (numer **cloud**) ;; -> takes in one of those 'clouds' and returns numerator : (denom **cloud**) ;; -> takes in one of those 'clouds' and returns denominator how 'cloud' is made is not our problem: we dont want to know being able to leverage a 'cloud' though will give us the ability to work #+BEGIN_SRC scheme (define (+rat x y) (make-rat (+ (* (numer x)(denom y)) (* (numer y)(denom x))) (* (denom x) (denom y)))) #+END_SRC no problem at all, if we have these 'clouds' we can also implement the product of 2 rats #+BEGIN_SRC scheme (define (*rat x y) (make-rat (* (numer x) (numer y)) (* (denom x) (denom y)))) #+END_SRC we assumed by wishful thinking that we had a data object we assumed we had a way to make one, a "constructor" - make-rat we assumed we had ways to get things out, "selectors" - denom - numer without abstractions: more importantly thon confusing our programming, we might confuse our mind --> break we need a glue for data objects. lisp provides the glue via LIST STRUCTURE via PAIRS 'cons' taking two args and returning a pair 'car' selecting the first part of a pair 'cdr' selecting the second part of a pair there is a "box and pointer" notation which i wont try to draw in ascii art here today with these data glue primitives, we can easily define the 'clouds' #+BEGIN_SRC scheme (define (make-rat n d) (cons n d)) (define (numer x) (car x)) (define (denom x) (cdr x)) #+END_SRC for : 1 1 : --- + --- : 2 4 : (define a (make-rat 1 2)) : (define b (make-rat 1 4)) : (define ans (+rat a b)) : (numer ans) ;; 6 : (denom ans) ;; 8 our implementation does not reduce to lowest terms #+BEGIN_SRC scheme (define (make-rat n d) (let ((g (gcd n d))) (cons (/ n g) (/ d g)))) #+END_SRC DATA ABSTRACTION: : we have *rat, +rat, etc !!the use of data : ------------------------------------------- : abstraction layer: make-rat/numer/denom : ------------------------------------------- : implemented via pairs !!the representation of data ableson said "bs" O_O why bother with data abstraction? goes back to the sorceress' power over a spirit if she has its name when programming, we are forced to make decisions. in general, for flexibility, we'd like to never make a decision until we absolutely have to. there's a fine line between deferring decisions and outright procrastination. we'd like to make progress and also never be bound by the consequences of our decisions. data abstraction allows this. we used wishful thinking. WE GAVE A NAME TO THE DECISION. then we continued as if decisions had been made. sometimes the decision never has to be made. !! GJS: "there's a good part of computer science that's a lot like magic. theres a bad part that's a lot like religion" ---> break its not so great that we can do rational arithmetic. it is great that we can use these as building blocks for something more complex imagine points in a plane, like the point p(1,2) we can make a system for representing points in a plane #+BEGIN_SRC scheme (define (make-vector x y) (cons x y)) ;; constructor (define (xcor p) (car p)) ;; selector (define (ycor p) (cdr p)) ;; selector #+END_SRC given points in a plane, we might want to use them to build something. we might want to talk about line segments connecting points. #+BEGIN_SRC scheme (define (make-seg p q) (cons p q)) (define (seg-start s) (car s)) (define (seg-end s) (cdr s)) (define (midpoint s) (let ((a (seg-start s)) (b (seg-end s))) (make-vector (average (xcor a) (xcor b)) (average (ycor a) (ycor b))))) (define (length s) (let ((dx (- (xcor (seg-end s)) (xcor (seg-start s)))) (dy (- (ycor (seg-end s)) (ycor (seg-start s))))) (sqrt (+ (square dx) (square dy))))) #+END_SRC here we have built a LAYERED SYSTEM : : SEGMENTS : : ----------------------------\ abstraction layer : make-seg/seg-start/seg-end : ----------------------------------------------- : : VECTORS : : ----------------------------\ abstraction layer : make-vector/xcor/ycor : ----------------------------------------------- : : PAIRS : this grows quite naturally bc pairs can themselves point to other pairs etc one of abelson's fav words: !! CLOSURE when you put things together, you can then put those things together, like pairs of pairs ---> break "its always harder in computer science to talk about what something means than to go off and do it" with - make-rat - numer - denom we have /abstract data/ it fulfills a contract: : IF x = (make-rat n d) : THEN : (numer x) n : --------- = --- : (denom x) d abelson: "let me do something that i think is really going to terrify you" : AXIOM FOR PAIRS: : FOR ANY x AND y : (car (cons x y)) IS x : (cdr (cons x y)) IS y what might we build pairs from? whats below the pair abstraction?? abelson says pairs can be built from *nothing at all*, pure abstraction #+BEGIN_SRC scheme (define (cons a b) (lambda (pick) (cond ((= pick 1) a) ((= pick 2) b)))) (define (car x) (x 1)) (define (cdr x) (x 2)) #+END_SRC there are no data objects! only procedures! it's built out of air we dont need data at all to build data abstractions ONCE AGAIN we blur the line between data and procedure