(Lispex)sicp.io
2.7 · Data-directed dispatch

A type tag chooses the representation-specific operation.

A generic interface can combine an operation name with a data type, then retrieve the matching procedure from one table instead of branching at every caller.

Guiding question

How does an operation table preserve one interface across different representations?

  • Attach an explicit type tag to representation contents
  • Use an operation and type pair as a dispatch key
  • Keep rectangular and polar magnitude formulas separate
  • Call one generic magnitude interface for both representations

Each table entry pairs the key (magnitude type) with a procedure that understands only that type’s contents. The rectangular procedure computes the square root of x squared plus y squared, while the polar procedure reads the stored radius.

apply-generic removes the tag only after get has selected the matching procedure. Client code names magnitude and supplies tagged data without asking which representation it contains. Adding a representation changes the table rather than the generic interface.

Lispex · SICP sourceScheme-compatible SICP syntax executed by the Lispex SICP profile.
(begin
  (define operation-table
    (list
      (cons (list 'magnitude 'rectangular)
            (lambda (contents)
              (sqrt (+ (* (car contents) (car contents))
                       (* (cadr contents) (cadr contents))))))
      (cons (list 'magnitude 'polar)
            (lambda (contents) (car contents)))))
  (define (get operation type table)
    (cond ((null? table) #f)
          ((and (eq? operation (car (car (car table))))
                (eq? type (cadr (car (car table)))))
           (cdr (car table)))
          (else (get operation type (cdr table)))))
  (define (attach-tag type contents) (cons type contents))
  (define (apply-generic operation object)
    (let ((procedure (get operation (car object) operation-table)))
      (procedure (cdr object))))
  (list
    (apply-generic 'magnitude
                   (attach-tag 'rectangular (list 3.0 4.0)))
    (apply-generic 'magnitude
                   (attach-tag 'polar (list 5.0 0.0)))))
Lispex learning runtimeLispex SICP profile 1.0.0
Loading Lispex SICP runtime
Lispex · SICP source969 / 1,048,576 UTF-8 bytes
Examples
Result
Output
Value
Diagnostic
Visible execution0 / 0 trace events
    This browser result is not a Lispex Vouch record or authority.wasm —
    Expected observation

    The first program returns (5.0 5.0). The second returns (13.0 13.0).

    Trace focus

    Follow get comparing the operation and type key before apply-generic passes only contents to the selected procedure. The rectangular run reaches sqrt, while the polar run returns the first content field.

    Try it yourself

    Change the program before you read the hint.

    Add a magnitude entry for a one-dimensional representation tagged linear, then call the unchanged apply-generic interface with a stored length of 9.0.

    Show one hint

    The new key is (magnitude linear). Its procedure can return the first content field.