1 / 49

Lecture 1 4

Lecture 1 4. - Environment Model (cont.) - Mutation - Stacks and Queues. Example: explaining make-counter. Counter: something which counts up from a number (define make-counter (lambda (n) (lambda () (set! n (+ n 1)) n )))

simonhines
Télécharger la présentation

Lecture 1 4

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Lecture 14 - Environment Model (cont.) - Mutation- Stacks and Queues מבוא מורחב - שיעור 14

  2. Example: explaining make-counter Counter: something which counts up from a number (define make-counter (lambda (n) (lambda () (set! n (+ n 1)) n ))) (define ca (make-counter 0))(ca) ==> 1(ca) ==> 2(define cb (make-counter 0))(cb) ==> 1(ca) ==> 3(cb) ==> 2 2

  3. (define ca (make-counter 0)) | GE make-counter: GE ca: E1 p: nb:(lambda () (set! n (+ n 1)) n) p: b:(set! n (+ n 1)) n n: 0 environment pointerpoints to E1because the lambdawas evaluated in E1 (lambda () (set! n (+ n 1)) n) | E1 3

  4. (ca) | GE make-counter: GE ca: E1 1 n: 0 p: nb:(lambda () (set! n (+ n 1)) n) E2 p: b:(set! n (+ n 1)) n ==> 1 empty (set! n (+ n 1)) | E2 n | E2 ==> 1 4

  5. (ca) | GE make-counter: GE ca: E1 1 n: 0 p: nb:(lambda () (set! n (+ n 1)) n) 2 E3 p: b:(set! n (+ n 1)) n ==> 2 empty (set! n (+ n 1)) | E3 n | E3 ==> 2 5

  6. (define cb (make-counter 0)) | GE make-counter: GE cb: ca: E1 E4 n: 2 p: nb:(lambda () (set! n (+ n 1)) n) E3 p: b:(set! n (+ n 1)) n p: b:(set! n (+ n 1)) n n: 0 (lambda () (set! n (+ n 1)) n) | E4 6

  7. (cb) | GE make-counter: GE ca: cb: E1 E4 n: 2 n: 0 p: nb:(lambda () (set! n (+ n 1)) n) 1 E2 E5 p: b:(set! n (+ n 1)) n p: b:(set! n (+ n 1)) n ==> 1 7

  8. Capturing state in local frames & procedures make-counter: GE ca: cb: E1 E4 n: 2 n: 1 p: nb:(lambda () (set! n (+ n 1)) n) E2 p: b:(set! n (+ n 1)) n p: b:(set! n (+ n 1)) n 8

  9. Lessons from the make-counter example Environment diagrams get complicated very quickly Rules are meant for the computer to follow, not to help humans A lambda inside a procedure body captures theframe that was active when the lambda was evaluated this effect can be used to store local state 9

  10. Explaining Nested Definitions Nested definitions : block structure (define (sqrt x) (define (good-enough? guess) (< (abs (- (square guess) x)) 0.001)) (define (improve guess) (average guess (/ x guess))) (define (sqrt-iter guess) (if (good-enough? guess) guess (sqrt-iter (improve guess)))) (sqrt-iter 1.0)) מבוא מורחב - שיעור 13 10

  11. (sqrt 2) | GE sqrt: GE E1 x: 2 good-enough: improve: sqrt-iter: p: xb:(define good-enou ..) (define improve ..) (define sqrt-iter ..) (sqrt-iter 1.0) p: guessb:(< (abs ….) The same x in all subprocedures guess: 1 sqrt-iter guess: 1 good-enou? מבוא מורחב - שיעור 13 11

  12. message passing example (define (cons x y) (define (dispatch op) (cond ((eq? op 'car) x) ((eq? op 'cdr) y) (else (error "Unknown op -- CONS" op)))) dispatch) (define (car x) (x 'car)) (define (cdr x) (x 'cdr)) (define a (cons 1 2)) (car a) מבוא מורחב - שיעור 13 12

  13. (define a (cons 1 2)) | GE cons: GE E1 x: 1 y: 2 p: x yb:(define (dispatch op) ..) dispatch dispatch: p: op b:(cond ((eq? op 'car) x) .... ) car: cdr: a: p: xb:(x ‘cdr) p: xb:(x ‘car) מבוא מורחב - שיעור 13 13

  14. (car a) | GE cons: GE p: x yb:(define (dispatch op) ..) dispatch E2 x: p: op b:(cond ((eq? op 'car) x) .... ) op: ‘car E3 ==> 1 car: cdr: a: E1 x: 1 y: 2 p: xb:(x ‘cdr) p: xb:(x ‘car) dispatch: (x ‘car) | E2 מבוא מורחב - שיעור 13 (cond ..) | E3 ==> 1 14

  15. Mutating Compound Data • constructor: (cons x y) creates a new pair p • selectors: (car p) returns car part of pair (cdr p) returns cdr part of pai • mutators: (set-car! p new-x) changes car pointer in pair (set-cdr! p new-y) changes cdr pointer in pair ; Pair ×anytype  undef -- side-effect only! set-car! and set-cdr! are procedures, while set! is a special form מבוא מורחב - שיעור 14

  16. a X b red blue 10 Example: Pair/List Mutation (define a (list ‘red ‘blue)) (red blue) a ==> (define b a) b ==> (red blue) (set-car! a 10) a ==> (10 ‘blue) b ==> (10 ‘blue) מבוא מורחב - שיעור 14

  17. d c X red blue 10 red blue Compare this with… (define c (list ‘red ‘blue)) (define d (list ‘red ‘blue)) c ==> (red blue) d ==> (red blue) (set-car! c 10) c ==> (10 blue) d ==> (red blue) מבוא מורחב - שיעור 14

  18. c a d X X b red red blue blue 10 10 red blue Equivalent vs. The Same In the first example a and b are the same. A change to one changes the other. They point to a single object. In the second example c and d have at first the same value, but later on one changes and the other does not.They just happen to have at some point in time the same value. Without mutation, there is no “identity”: equality of value is all we have מבוא מורחב - שיעור 14

  19. x a b 1 2 Example 2: Pair/List Mutation (define x (list 'a 'b)) (set-car! (cdr x) (list 1 2)) • Eval (cdr x) to get a pair object • Change car pointer of that pair object X (a ( 1 2)) מבוא מורחב - שיעור 14

  20. x 1 2 Can create cyclic structures (define x (list 1 2)) (cddr x) ==>() (set-cdr! (cdr x) x) (caddr x) ==> 1 • Beware of infinite scanning (or printing). • Dr. Scheme prevents the infinite printing of returned values (sometimes). Prints some indication: • x ==>#0=(1 2 . #0#) מבוא מורחב - שיעור 14

  21. Eq? vs. Equal? • To check whether two names point to the same object: Test witheq? (eq? a b) ==> #t • To check whether two elements currently have the same content: Test withequal? (equal? (list 1 2) (list 1 2)) ==> #t(eq? (list 1 2) (list 1 2)) ==> #f מבוא מורחב - שיעור 14

  22. x X 3 4 y X X 7 1 2 Lets go over the following: x ==> (3 4) y ==> (1 2) (set-car! x y) x ==> (set-cdr! y (cdr x)) x ==> (set-cdr! x (list 7) x ==> ((1 2) 4) ((1 4) 4) ((1 4) 7) מבוא מורחב - שיעור 14

  23. We can actually get away only with set! (define (cons x y) (define (change-car val) (set! x val)) (define (change-cdr val) (set! y val)) (lambda (m) (cond ((eq? m 'car) x) ((eq? m 'cdr) y) ((eq? m 'set-car!) change-car) ((eq? m 'set-cdr!) change-cdr) (else (error "Undefined operation“ m))))) מבוא מורחב - שיעור 14

  24. We can actually get away only with set! (define (car z) (z 'car)) (define (cdr z) (z 'cdr)) (define (set-car! z new-value) ((z 'set-car!) new-value) z) (define (set-cdr! z new-value) ((z 'set-cdr!) new-value) z) • Saw that pairs can be implemented with functions. • Now we see that pair mutation can be implemented with functions and set! • But set! is an essential addition. מבוא מורחב - שיעור 14

  25. Insert Insert Insert Stack Data Abstraction Last in, First out. Insert Delete מבוא מורחב - שיעור 14

  26. Stack Data Abstraction • constructor:(make-stack) returns an empty stack • selectors:(top stack) returns current top element from a stack • operations:(insert stack elem) returns a new stack with the element added to the top of the stack (push) (delete stack) returns a new stack with the top element removed from the stack (pop) (empty-stack? stack) returns #t if no elements, #f otherwise contract: (delete stack) require (not (empty-stack? stack)) (top stack) require (not (empty-stack? stack)) ensure (equal? (delete (insert stack elem)) stack) ensure (equal? (top (insert stack elem)) elem) מבוא מורחב - שיעור 14

  27. Stack Implementation Strategy • implement a stack as a list a b d • we will insert and delete items at the front of the stack מבוא מורחב - שיעור 14

  28. Stack Implementation (define (make-stack) nil) (define (empty-stack? stack) (null? stack)) (define (insert stack elem) (cons elem stack)) (define (delete stack) (if (empty-stack? stack) (error "stack underflow – delete") (cdr stack))) (define (top stack) (if (empty-stack? stack) (error "stack underflow – top") (car stack))) מבוא מורחב - שיעור 14

  29. Limitations in our Stack • Stack does not have identity (define s (make-stack)) s ==> () (insert s 'a) ==> (a) s ==> () (set! s (insert s 'b)) s ==> (b) מבוא מורחב - שיעור 14

  30. (delete! s) s X d c a stack Mutable Stack Implementation • The data type contains a list of elements – as before. • Insert and delete mutate a stack object. • The first element of the list is special to distinguish Stack objects from other lists – defensive programming The stack will be a mutable data type. מבוא מורחב - שיעור 14

  31. Mutable Stack Data Abstraction • constructor:(make-stack) returns an empty stack • queries (selectors):(top stack) returns current top element from a stack(empty-stack? stack) returns #t if no elements, #f otherwise (stack? any) returns #t if any is a stack, #f otherwise • command (mutators, transformers):(insert! stack elem) modify the stack by adding elem to the top of the stack (push) (delete! stack) modify the stack by removing the top element from the stack (pop) stack? is really not part of the stack abstraction מבוא מורחב - שיעור 14

  32. (define (make-stack) (cons 'stack nil)) Mutable Stack Implementation (1) (define (stack? stack) (and (pair? stack) (eq? 'stack (car stack)))) (define (empty-stack? stack) (null? (cdr stack))) (define (top stack) (if (empty-stack? stack) (error "stack underflow – top") (cadr stack))) מבוא מורחב - שיעור 14

  33. Mutable Stack Implementation (2) (define (insert! stack elem) (set-cdr! stack (cons elem (cdr stack))) stack)) (define (delete! stack) (if (empty-stack? stack) (error "stack underflow – delete") (set-cdr! stack (cddr stack))) stack) Here the mutators return the stack. May choose to return a neutral value, eg. ‘ok or nothing (more later) מבוא מורחב - שיעור 14

  34. Mutatable vs. functional • The decision between a mutable stack and a functional stack is part of the contract • Changing this changes the abstraction! • The user should know if the object mutates or not in order to use the abstraction correctly: • For example, if we write (define stack1 stack2) can stack1 later change because of changes to stack2 ? מבוא מורחב - שיעור 14

  35. Insert Insert Insert x2 x3 x1 front A Queue FIFO: First In, First Out מבוא מורחב - שיעור 14

  36. front A Queue Insert Insert FIFO: First In, First Out Insert x3 x2 Delete מבוא מורחב - שיעור 14

  37. b c d A Queue Implementation A queue is a list of queue elements: • The front of the queue is the first element in the list • To insert an element at the tail of the queue, need to scan the entire list, then attach the new element at the rear: b c d new מבוא מורחב - שיעור 14

  38. A Queue Implementation (Cont) (define (make-queue) null) (define (empty-queue? q) (null? q)) (define (front-queue q) (if (empty-queue? q) (error "front of empty queue:" q) (car q))) (define (delete-queue q) (if (empty-queue? q) (error "delete of empty queue:" q) (cdr q))) (define (insert-queue q elt) (if (empty-queue? q) (cons elt nil) (cons (car q) (insert-queue (cdr q) elt)))) מבוא מורחב - שיעור 14

  39. Complexity of the implementation For a queue of length n • Time required -- number of cons, car, cdr calls? • Space required -- number of new cons cells? front-queue, delete-queue: • Time: T(n) = Θ(1) that is, constant in time • Space: S(n) = Θ(1) that is, constant in space insert-queue: • Time: T(n) = Θ(n) that is, linear in time • Space: S(n) = Θ(n) that is, linear in space מבוא מורחב - שיעור 14

  40. Mutable Queue Data Abstraction • constructor:(make-queue) returns an empty queue • queries (selectors, assessors): (front-queue q) returns the object at the front of the queue. If queue is empty signals error (empty-queue? q) tests if the queue is empty • commands (mutators, transformers) :(insert-queue! q elt)inserts the elt at the rear of the queue and returns ‘ok (delete-queue! q)removes the elt at the front of the queue and returns ‘ok • additional query: (queue? q) tests if the object is a queue מבוא מורחב - שיעור 14

  41. rear-ptr front-ptr queue a b c d Implementation • We attach a type tag as before. • Maintain queue identity • Build a structure to hold: • a list of items in the queue • a pointer to the front of the queue • a pointer to the rear of the queue מבוא מורחב - שיעור 14

  42. rear-ptr front-ptr queue a b c d Queue Helper Procedures Hidden inside the abstraction (define (front-ptr q) (cadr q)) (define (rear-ptr q) (cddr q)) (define (set-front-ptr! q item) (set-car! (cdr q) item)) (define (set-rear-ptr! q item) (set-cdr! (cdr q) item)) מבוא מורחב - שיעור 14

  43. Queue implementation (define (make-queue) (cons 'queue (cons null null))) (define (queue? q) (and (pair? q) (eq? 'queue (car q)))) (define (empty-queue? q) (if (not (queue? q)) (error "object not a queue:" q) (null? (front-ptr q)))) (define (front-queue q) (if (empty-queue? q) (error "front of empty queue:" q) (car (front-ptr q)))) מבוא מורחב - שיעור 14

  44. new-pair rear-ptr rear-ptr front-ptr queue e a b c d Queue implementation – Insert (define (insert-queue! q elt) (let ((new-pair (cons elt nil))) (cond ((empty-queue? q) (set-front-ptr! q new-pair) (set-rear-ptr! q new-pair) ‘ok) (else (set-cdr! (rear-ptr q) new-pair) (set-rear-ptr! q new-pair) ‘ok)))) מבוא מורחב - שיעור 14

  45. rear-ptr front-ptr queue a b c d Queue implementation - delete (define (delete-queue! q) (cond ((empty-queue? q) (error "delete of empty queue:" q)) (else (set-front-ptr! q (cdr (front-ptr q))) ‘ok))) מבוא מורחב - שיעור 14

  46. Time and Space complexities ? O(1) מבוא מורחב - שיעור 14

  47. Programming Styles – Procedural vs. Object-Oriented • Procedural programming - Organize system around procedures that operate on data: (do-something <data> <arg> ...) (do-another-thing <data>) • Object-based programming - Organize system around objectsthat receive messages • ((<object> 'do-something) <arg>) • ((<object> 'do-another-thing) ... ) • An object encapsulates data and operations • Message passing and returned procedures are the means to write object oriented code in scheme מבוא מורחב - שיעור 14

  48. Stacks in OO style (define (make-stack) (let ((top-ptr '())) (define (empty?) (null? top-ptr)) (define (delete!) (if (null? top-ptr) (error . . .) (set! top-ptr (cdr top-ptr))) top-ptr ) (define (insert! elmt) (set! top-ptr (cons elmt top-ptr)) top-ptr) (define (top) (if (null? top-ptr) (error . . .) (car top-ptr))) (define (dispatch op) (cond ((eq? op 'empty?) empty?) ((eq? op 'top) top) ((eq? op 'insert!) insert!) ((eq? op 'delete!) delete!))) dispatch)) מבוא מורחב - שיעור 14

  49. Stacks in OO style (define s (make-stack)) ((s 'insert!) 'a) ==> ((s 'insert!) 'b) ==> ((s 'top)) ==> ((s 'delete!)) ==> ((s 'top)) ==> ((s 'delete!)) ==> (a) (b a) b (a) a () • compare with message passing examples: in OO we do not hide behind a functional layer eg. • (define (insert! s ‘a) ((s insert!) ‘a)) • In OO programming languages the notation is eg. • s.insert(a) • s.delete() מבוא מורחב - שיעור 14

More Related