« Back to James's CS61A page. | CS61A: Spring 2000 |
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 is pretty straightforward; we attach a
Once we tag data, what can we do with it?
The conventional style is to write operators that explicitly check for each data type and then do the Right Thing.
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 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!
(define z (make-from-real-imag 3 4))
This binds z to the dispatch procedure returned by
(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
« Week 5 | Week 7 » |
« Back to James's CS61A page. | CS61A: Spring 2000 |
Last Modified: Tuesday, 30-Dec-2014 11:58:34 PST