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)