Object Systems Built from Closures

*"Objects are a poor man's closures; closures are a poor man's objects."* Real Lisp object systems: CLOS (Common Lisp), Racket's class system, Clojure protocols/records, Emacs EIEIO, and GOOPS (Guile).

;; Objects = closures + message dispatch
(define (make-point x y)
  (define (dispatch msg . args)
    (case msg
      ((x) x)
      ((y) y)
      ((move!) (set! x (+ x (car args))) (set! y (+ y (cadr args))))
      ((to-string) (string-append "(" (number->string x) ", " (number->string y) ")"))
      (else (error "Unknown message" msg))))
  dispatch)

(define p (make-point 1 2))
(p 'move! 3 4)
(p 'to-string)                            ; "(4, 6)"

;; Inheritance by delegation
(define (make-colored-point x y color)
  (let ((parent (make-point x y)))
    (lambda (msg . args)
      (case msg
        ((color) color)
        (else (apply parent msg args))))))
(define cp (make-colored-point 0 0 'red))
(cp 'color)                               ; red
(cp 'x)                                   ; 0 (delegated)