Docstoc

il scheme mavo spring lectures

Document Sample
il scheme mavo spring lectures Powered By Docstoc
					Lecture 12


Data directed programming
Message passing
dotted-tail notation & apply
Section 2.4, pages 169-187
2.5.1,2.5.2 pages 187-197
(but with a different example)




                                 12 ‫מבוא מורחב - שיעור‬
                                                         1
Multiple Representations of Abstract Data
            Example: geometrical figures




• We develop a package for handling geometrical figures
• Each figure has a unique data representation
• Want to support Generic Operations on figures, such as:
   • Compute figure area
   • Compute figure circumference
   • Print figure parameters, etc.

                         12 ‫מבוא מורחב - שיעור‬
                                                          2
           Geometrical figures: interface
Constructors:
(make-rectangle width height)
(make-circle radius)
(make-square length)

Rectangle implementation
  .
  .
Circle implementation
  .
  .
Square implementation
  .
  .
Generic operations:
(area figure)
(circumference figure)
(fig-display figure)
  .
  .
We will now see 3 alternative implementations…
                       12 ‫מבוא מורחב - שיעור‬
                                                 3
 Implementation #1: tagged data

• Main idea: add a tag (symbol) to every figure
  instance
• Generic procedures dispatch on parameter type



       ('circle 2)



       ('square 1)




       ('rectangle 1 . 2)

                  12 ‫מבוא מורחב - שיעור‬
                                                  4
  Attaching tags.

(define (attach-tag type-tag contents)
  (cons type-tag contents))

(define (type-tag datum)
  (if (pair? datum)
      (car datum)
      (error "Bad tagged datum -- TYPE-TAG" datum)))

(define (contents datum)
  (if (pair? datum)
      (cdr datum)
      (error "Bad tagged datum -- CONTENTS" datum)))



                     12 ‫מבוא מורחב - שיעור‬
                                                5
Tagged data: rectangle implementation
(define (make-rectangle width height)
   (attach-tag 'rectangle (cons width height)))

(define (width rect) (car rect))
(define (height rect) (cdr rect))

(define (circumference-rect rect)
  (* 2 (+ (width rect) (height rect))))

(define (area-rect rect)
  (* (width rect) (height rect)))

(define (fig-display-rect rect)
  (my-display "Rectangle: width, ” (width rect)
              ", height: " (height rect)))
assume my-display takes any number of arguments
and prints them.
                    12 ‫מבוא מורחב - שיעור‬
                                                  6
Tagged data: circle implementation
(define (make-circle radius)
   (attach-tag 'circle (list radius)))

(define PI 3.1415926)
(define (radius circle) (car circle))

(define (circumference-circle circle)
  (* 2 PI (radius circle)))

(define (area-circle circle)
  (let ((r (radius circle)))
    (* PI r r)))

(define (fig-display-circle circle)
  (my-display “Circle: radius, ” (radius circle)))



                    12 ‫מבוא מורחב - שיעור‬
                                                     7
  Tagged data: generic operations
(define (circumference fig)
   (cond ((eq? 'rectangle (type-tag fig))
          (circumference-rect (contents fig)))
         ((eq? 'circle (type-tag fig))
          (circumference-circle (contents fig)
         .
         .))
                                                         Dispatch
(define (area fig)                                       on type
   (cond ((eq? 'rectange (type-tag fig))
          (area-rect (contents fig)))
         ((eq? 'circle (type-tag fig))
          (area-circle (contents fig)
         .
         .))

(define (fig-display fig)
   (cond ((eq? 'rectange (type-tag fig))
          (fig-display-rectangle (contents
                                                fig)))
         ((eq? 'circle (type-tag fig))
          (fig-display-circle (contents fig)
         .
         .))              12 ‫מבוא מורחב - שיעור‬
                                                                    8
 The Difficulties
 The system is not additive/modular

The generic procedures must know about all types.
If we want to add a new type we need to
   • add it to each of the operations,
   • be careful with name clashes.

     (define (area fig)
        (cond ((eq? 'rectange (type-tag fig))
               (area-rect (contents fig)))
              ((eq? 'circle (type-tag fig))
               (area-circle (contents fig)
              .
              .))
                          12 ‫מבוא מורחב - שיעור‬
                                                    9
                     Implementation #2: data directed programming

                            • Main idea: work with a table.
                            • Keep a pointer to the right procedure to call in
                            the table, keyed by the operation/type combination

                                                               types
Generic operations




                                     Circle                      Rectangle       Square

                     circumference circumference-circle circumference-rect circumference-square

                     area          area-circle             area-rect          area-square

                     fig-display   fig-display-circle      fig-display-rect   fig-display-square



                                                  12 ‫מבוא מורחב - שיעור‬
                                                                                            10
Data-directed programming (Cont)
Assume we have a global two dimensional table and the
following operations on it:


(put key1 key2 val)                 Adds val to the table,
                                    under keys key1, key2



                                 Retrieves the value found in the
(get key1 key2)  val/#f         table under keys key1, key2
                                 OR #f if the value is not found



                        12 ‫מבוא מורחב - שיעור‬
                                                             11
Rectangle implementation
(define (install-rectangle-package)
  ;; Implementation
  (define (width rect) (car rect))
  (define (height rect) (cdr rect))
  (define (circumference rect)
     (* 2 (+ (width rect) (height rect))))
  (define (area rect)
     (* (width rect) (height rect)))
  (define (fig-display rect)
     (my-display "Rectangle: width ,” (width rect)
              “, height " (height rect)))
  (define (make-rect width height)
     (attach-tag 'rectangle (cons width height)))

  ;; Interface to the rest of the system
  (put 'circumference 'rectangle circumference)
  (put 'area 'rectangle area)
  (put 'fig-display 'rectangle fig-display)
  (put 'make-fig 'rectangle make-rect)
  'done)                12 ‫מבוא מורחב - שיעור‬
                                                     12
Circle implementation
(define (install-circle-package)
  ;; Implementation
  (define PI 3.1415926)
  (define (radius circle) (car circle))
  (define (circumference circle)
     (* 2 PI (radius circle)))
  (define (area circle)
     (let ((r (radius circle))
       (* PI r r)))
(define (fig-display circle)
  (my-display “Circle: radius,” (radius rect)))
  (define (make-circle radius)
     (attach-tag 'circle (list radius)))

  ;; Interface to the rest of the system
  (put 'circumference 'circle circumference)
  (put 'area 'circle area)
  (put 'fig-display 'circle fig-display)
  (put 'make-fig 'circle make-circle)
  'done)                12 ‫מבוא מורחב - שיעור‬
                                                  13
Generic procedures
(define (circumference fig)
   (apply-generic 'circumference fig))



(define (area fig)
   (apply-generic 'area fig))


(define (fig-display fig)
   (apply-generic 'fig-display fig))


Apply generic:

• Locates the right procedure in the table
• Calls it
• Passes the figure-data as a parameter
                       12 ‫מבוא מורחב - שיעור‬
                                               14
 Apply-generic
(define (apply-generic op arg)
  (let ((type (type-tag arg)))
   (let ((proc (get op type)))
      (if proc
          (proc (contents arg))
          (error
            "No operation for this type -- APPLY-GENERIC"
            op type-tag)))))



Get the type of the figure
Locate the procedure that implements op on that type
If there is such a procedure (get did not return #f)
   Call it and pass the figure-data as a parameter

                          12 ‫מבוא מורחב - שיעור‬
                                                            15
Summary: Data Directed programming
 Data Directed programming:
  The data (argument) triggers the right operation
  based on the data type.
Data Directed programming is more modular:

   1. To add a representation, we only need to write
      a package for the new representation without
      changing generic procedures. (Execute the install
       procedure once).
   2. Changes are local.
   3. No name clashes.

   install-circle-package
   install-rectangle-package
   ..                 12 ‫מבוא מורחב - שיעור‬
                                                          16
Implementation #3: Message Passing
       • Main idea: the figure is represented by a procedure
       • The procedure dispatches on the operation type

Data Directed: Intelligent operations that work with
               different data types.

Message Passing: Intelligent data types that support
                different operations.

In message passing the idea is that the data gets a message
that tells it which operation to invoke, and returns the result.


                          12 ‫מבוא מורחב - שיעור‬
                                                            17
                     Message Passing (cont’)

                     Data Directed: in each operation we dispatch on type.


                      Message Passing: in each type we dispatch on operation.

                                                               types
Generic operations




                                     Circle                      Rectangle       Square
                     circumference circumference-circle circumference-rect circumference-square

                     area          area-circle             area-rect          area-square

                     fig-display   fig-display-circle      fig-display-rect   fig-display-square


                                                  12 ‫מבוא מורחב - שיעור‬
                                                                                            18
 Message passing style – rectangle figure
The constructor has it all.
(define (make-rectangle width height)
  (lambda (op)
    (cond ((eq? op 'area) (* height width))
          ((eq? op 'circumference) (* 2 (+ width height)))
          ((eq? op 'fig-display)
              (my-display "Rectangle: width, ” width)
                          “height, " height))
          (else
           (error "Unknown op – MAKE-RECTANGLE" op)))))

                Another way to write this:

(define (make-rectangle width height)
  (define (dispatch op)
    (cond ... ;; as above
                                                      ))
  dispatch)                   12 ‫מבוא מורחב - שיעור‬
                                                             19
 Message passing style – circle figure

The constructor has it all.


(define (make-circle radius)
  (define PI 3.1415926)
  (lambda (op)
    (cond ((eq? op 'area) (* PI radius radius))
          ((eq? op 'circumference) (* 2 PI radius))
          ((eq? op 'fig-display)
              (my-display “Circle: radius ” radius))
          (else
            (error "Unknown op – MAKE-CIRCLE" op)))))




                              12 ‫מבוא מורחב - שיעור‬
                                                        20
Generic operations and new apply-generic
(define (circumference fig)
   (apply-generic 'circumference fig))



(define (area fig)
   (apply-generic 'area fig))


(define (fig-display fig)
   (apply-generic 'make-fig fig))




   (define (apply-generic op arg) (arg op))




                       12 ‫מבוא מורחב - שיעור‬
                                               21
Summary: Message Passing

• Additive
• Avoids name-clashes problems
• No need for a table
• More difficult to extend for multi-parameter operations




Message passing is the basis for Object Oriented
Programming and we will discuss it again later.



                        12 ‫מבוא מורחב - שיעור‬
                                                            22
 Writing procedures with a variable number
     of parameters (dotted-tail notation)
         At least two
         parameters must                           All other
         be passed                                 parameters will
                                                   be passed in a
                                                   list named ‘z’


(define (proc x y . z) <body>)



              This dot signifies that
              proc accepts a variable
              number of parameters
                           12 ‫מבוא מורחב - שיעור‬
                                                                     23
 Dotted-tail notation: examples
                                              x?
                                                1
(define (proc x y . z) <body>)
                                              y?
                                                2
(proc 1 2 3 4 5 6)
                                              z  ? 4 5 6)
                                                  (3



                                              x?
                                                1
(proc 1 2)
                                              y?
                                                2
                                              z?
                                                null



(proc 1)                                     ERROR

                      12 ‫מבוא מורחב - שיעור‬
                                                             24
 Dotted-tail notation: another example


(define (proc . z) <body>)
                                               z  ? 2 3 4 5 6)
                                                   (1
(proc 1 2 3 4 5 6)



(proc)                                        z  null
                                                   ?



(proc 1 (list 2 3))                           z  ? (2 3))
                                                   (1



                       12 ‫מבוא מורחב - שיעור‬
                                                                  25
Dotted-tail notation: another example
We want to implement a procedure (count…) that gets a
variable number of parameters and returns their number



(count 1 7 8 9 1)     5
(count 0)  1
(count)  0




(define (count . s) _________________)
                     (length s)



                      12 ‫מבוא מורחב - שיעור‬
                                                     26
 Dotted-tail notation: yet another example

(define (lt x . y)
  (length (filter (lambda (z) (< z x)) y)))


What does this procedure do ?
(lt 1 7 8 9 1 0 -1)       2
(lt 1000 1 10 0)  3
(lt 1)  0
(lt)  ERROR


lt returns the number of parameters
that are smaller than the first parameter.


                        12 ‫מבוא מורחב - שיעור‬
                                                27
The builtin procedure Apply
•Suppose we want to apply some procedure proc

•but the parameters are available as a list

                (apply proc lst)

  will give the same result as

     (proc v1 v2 … vn)

assuming lst is          (v1 v2 … vn)


                        12 ‫מבוא מורחב - שיעור‬
                                                28
Apply examples

(apply * (list 1 2 3))        6

(apply count (list 1 2 3))          3

(apply lt (list 10 1 2 3 11 9))  4

(apply append '((1) (2) (3) (4)))              (1 2 3 4)

(apply expt '(2 4))    16

(apply list '(1 2 3 4 5))  (1 2 3 4 5)




                      12 ‫מבוא מורחב - שיעור‬
                                                            29
  General map

(define (f x y z) (+ x (* 2 y) (* 5 z)))

(general-map f '(1 2 3) '(2 3 4) '(2 4 7))  (15 28 46)

 (define (general-map proc list1 . other-lists)
   (if (null? list1)
       '()
       (let ((lists (cons list1 other-lists)))
         (let ((firsts (simple-map car lists))
               (rests (simple-map cdr lists)))
           (cons (apply proc firsts)
                 (apply general-map (cons proc rests)))))))

 We use the names simple-map and general-map
 for clarity.
 The general procedure is actually called map.
                          12 ‫מבוא מורחב - שיעור‬
                                                              30
Another apply example
Exercise: Implement a procedure, add-abs, that
receives 0 or more numbers, and returns the
sum of their absolute values.

Examples:

(add-abs)  0
(add-abs 1 -2 -3 4)  10
(define (add-abs . l)
  (if (null? l)
                                                   Does not work!!
     0
                       (add-abs (cdr l))
     (+ (abs (car l)) _________________________)))
                           12 ‫מבוא מורחב - שיעור‬
                                                                31
Another apply example
Exercise: Implement a procedure, add-abs, that
receives 0 or more numbers, and returns the
sum of their absolute values.

Examples:

(add-abs)  0
(add-abs 1 -2 -3 4)  10
(define (add-abs . l)
  (if (null? l)
                                                   This is ok!
     0
                       (apply add-abs (cdr l))
     (+ (abs (car l)) _________________________)))
                           12 ‫מבוא מורחב - שיעור‬
                                                                 32
Another apply example (cont)
Exercise: Implement a procedure, add-abs, that
receives 0 or more numbers, and returns the
sum of their absolute values.


Another solution (also using apply).



(define (add-abs . l)
          + (map abs l)
  (apply ________________________))



                        12 ‫מבוא מורחב - שיעור‬
                                                 33

				
DOCUMENT INFO
Shared By:
Categories:
Tags:
Stats:
views:9
posted:8/4/2011
language:English
pages:33