# Type Dispatching and Message Passing

SICP describes two ways by which we can call the functions associated with the given data: Dispatch by type, and Message passing.

These are just the ways (as is almost everything else in the book) of creating a new layer of abstraction on the top of what we already have. The use cases are different, but the end result is the same: call the methods associated with the data.

Dispatch by type is used in *data-driven programming* where the incoming data
contains the necessary information of handling it. In this approach, we have a
generic operation which needs to be applied to a given type. The type itself may
be a generic type at a very high level of abstraction, but the data contains
enough information to direct the operation to the necessary subtype. Therefore,
this is a mapping from operation to type.

For example, given an operation like `Add`

and a generic type like `Number`

(which can be `Real`

or `Complex`

– the latter being an abstraction on two
integral/real numbers), the flow of dispatching by type will go to Number, then
to either Real or Complex, and if the number is Complex, then to it’s individual
parts.

In the book, this is done by tagging the data based on type. The upper layers of abstraction are used for bookkeeping and redirection, and the lower levels do the real work of handling data. As data moves from top to bottom, the tags are checked removed and the data is directed based on the value of tags; which are added again when the data needs to move up.

The other concept is Message Passing wherein we follow a 90° approach. Here we already have the type which provides a set of operations, and we pick the one we need and apply it to the data. Essentially we are sending a message to the data to apply a given operation.

The following code implements a table by using lists and exposing the functions which can work with the table.

We are creating an object in the function `create-table`

and pass back another
function `dispatch`

which receives the method name as a string, and returns the
unexposed function from the object. This function uses the parameters and do
whatever is asked of it.

```
(define (create-table)
(define table '())
(define (new-node k v)
(cons k v))
(define (get-key node)
(car node))
(define (get-value node)
(cdr node))
(define (insert k v)
(set! table (cons (new-node k v) table)))
(define (get k) (get-value-from-table k table))
(define (get-value-from-table k table)
(cond ((null? table) false)
((eq? (get-key (car table)) k)
(get-value (car table)))
(else (get-value-from-table k (cdr table)))))
(define (update-table k v) (update k v table))
(define (update k v table)
(cond ((null? table) false)
((eq? (get-key (car table)) k)
(set-car! table (new-node k v))
true)
(else (update k v (cdr table)))))
(define (update-value v node)
(set-cdr! node v))
(define (dispatch operation)
(cond ((eq? operation 'update)
update-table)
((eq? operation 'insert)
insert)
((eq? operation 'show)
table)
((eq? operation 'get)
get)))
dispatch)
;; The following four create better abstactions for the table.
(define insert (lambda (table k v) ((table 'insert) k v)))
(define update (lambda (table k v) ((table 'update) k v)))
(define get (lambda (table k) ((table 'get) k)))
(define show (lambda (table) (table 'show)))
```

Now using this code, we are going to implement both type-dispatch, and message passing. The following table helps in visualizing the connections between types (polar/rectangular) and functions (real-part, imag-part).

polar | rectangular | |
---|---|---|

real-part | # |
# |

imaginary-part | # |
# |

## Type Dispatch

This means that we will have an operation which will be applied to the given
type, e.g. We are given `real-part`

which needs to be applied to `polar`

. In
some pseudo language (Haskellish), this will be the syntax of the operation:

```
real-part (Polar x y) = x * cos y
imag-part (Polar x y) = x * sin y
real-part (Rect x y) = x
imag-part (Rect x y) = y
```

Given the structure of the table above, we will have the data structured in the table like:

```
(define real-part (create-table))
;; In polar, representation: (2,4) = 2 + 4j
;; In rectangular, representation: (2,4) => 2 is the radius, 4 is the angle
(insert real-part 'polar (lambda (z) (car z)))
(insert real-part 'rectangular (lambda (z) (* (car z) (cos (cdr z)))))
(define imag-part (create-table))
(insert imag-part 'polar (lambda (z) (cdr z)))
(insert imag-part 'rectangular (lambda (z) (* (car z) (sin (cdr z)))))
(define op-table (create-table))
(insert op-table 'real-part real-part)
(insert op-table 'imag-part imag-part)
-- usage:
> ((get-op op-table 'real-part 'polar) (cons 3 5))
3
> ((get-op op-table 'real-part 'rectangular) (cons 3 5))
0.850986556389678
```

On the other hand, we have the message passing scheme, wherein we have the data
first, and the operation. It is up to the data to correctly apply the operation
and return the result. With respect to the table, we are moving from top to
bottom: `polar.real-part`

, `polar.imag-part`

, `rect.real-part`

, etc.

The implementation in scheme is:

```
(define polar (create-table))
;; In polar representation: (2,4) = 2 + 4j
(insert polar 'real-part (lambda (z) (car z)))
(insert polar 'imag-part (lambda (z) (cdr z)))
(define rectangular (create-table))
;; In rectangular representation: (2,4) = (r, theta)
(insert rectangular 'magnitude (lambda (z) (car z)))
(insert rectangular 'angle (lambda (z) (cdr z)))
(define function-table (create-table))
(insert function-table 'polar polar)
(insert function-table 'rectangular rectangular)
```

Interestingly, the table itself implements the message-passing style since:

- Each table is a different object having its own copies of these methods (which should be shared when the code is running)
- We are passing each object the name of the operation to run.