« Back to James's CS61A page. CS61A: Spring 2000

Week 6 Discussion/Lab Notes


Administrivia


Maintenance

In the software life cycle, usually 30% of cost is spent on actual development and 70% is spent on maintenance. Maintenance includes adding support for new features in addition to correcting bugs.

It's impossible to predict the needs of your users perfectly in advance, so even if you write code without any errors, maintenance is inevitable. Unfortunately, maintaining code sucks.

One problem when maintaining code is that if you haven't worked on it in a while, you probably won't remember exactly how it works. Even worse, you might be maintaining code somebody else wrote and have never seen before.

Suppose we needed to add new data types to an existing system. We would like to have orthogonal code. That is, we would like to be able to add these new data types independently of the existing code. We want to modify the existing code as little as possible to reduce the risk of breaking something.


Tagged Data

Tagged data is pretty straightforward; we attach a type-tag to compound data so that we can identify it.

Once we tag data, what can we do with it?


Conventional (Explicit Dispatch)

The conventional style is to write operators that explicitly check for each data type and then do the Right Thing.


Data-Directed Programming (DDP)

The data-directed programming style is to write separate procedures for separate data types. We can then put these procedures into a data structure (such as a table), from which we can look up how to do the Right Thing based on particular data types and operations.

DDP is orthogonal. We can add operations without modifying existing code; we can add data types without modifying existing code.

Something to keep in mind: DDP does not necessarily need to use tables!


Message Passing

Message passing is essentially the opposite of explicit dispatch. Rather than having operators check for specific types, we have types that check for specific operations.

Message passing is perhaps the most confusing of the three styles. Let's look at an example from the textbook (page 186):

   (define (make-from-real-imag 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 -- MAKE-FROM-REAL-IMAG" op))))
     dispatch)

The most common source of confusion is the last line: Why aren't there parentheses around dispatch? where's the argument? what's going on?

We are not calling the dispatch procedure! make-from-real-imag returns the dispatch procedure. make-from-real-imag is a constructor for complex numbers; we don't pass messages to it, we pass messages to what it returns. Let's look at how we'd use actually this:

   (define z (make-from-real-imag 3 4))

This binds z to the dispatch procedure returned by (make-from-real-imag 3 4). z is a procedure that takes messages as arguments. Therefore we then can do:

   (z 'real-part)
   3

   (z 'imag-part)
   4

   (z 'magnitude)
   5

   (z 'angle)
   0.927295218001612

It's important that you understand this, because message passing is also the style we'll see the most of in this course. It is used as the basis to implement the object-oriented system we'll see next week.

Note that message passing does not use type-tags.


« Week 5 Week 7 »
« Back to James's CS61A page. CS61A: Spring 2000

Last Modified: Tuesday, 30-Dec-2014 11:58:34 PST