Objects via Closures and Message Passing

Scheme has no built-in object system; you can build one with closures (as above) or use an implementation's system (GOOPS, Racket classes, Chicken coops, TinyCLOS). See Module 46.

(define (make-account balance)
  (define (withdraw amount)
    (if (>= balance amount)
        (begin (set! balance (- balance amount)) balance)
        (error "Insufficient funds" amount)))
  (define (deposit amount)
    (set! balance (+ balance amount))
    balance)
  (define (dispatch m)
    (cond ((eq? m 'withdraw) withdraw)
          ((eq? m 'deposit) deposit)
          ((eq? m 'balance) balance)
          (else (error "Unknown request" m))))
  dispatch)

(define acc (make-account 100))
((acc 'withdraw) 30)                 ; 70
((acc 'deposit) 50)                  ; 120
(acc 'balance)                       ; 120

;; Inheritance by delegation
(define (make-savings-account balance rate)
  (let ((parent (make-account balance)))
    (lambda (m)
      (case m
        ((add-interest!) (lambda () ((parent 'deposit) (* (parent 'balance) rate))))
        (else (parent m))))))
(define sav (make-savings-account 1000 0.05))
((sav 'add-interest!))               ; 1050.0