Interfaces

;; a protocol lists the methods a type must answer to
(defprotocol Car
  (start-engine [this])
  (stop-engine [this]))

;; the record itself is immutable, so the changing state lives in an atom
(defrecord SportCar [started]
  Car
  (start-engine [this]
    (if @started
      false
      (do (println "start engine")
          (reset! started true)
          true)))
  (stop-engine [this]
    (println "stop engine")
    (reset! started false)))

(def car (->SportCar (atom false)))
(println "started is" (start-engine car))
;; the second call finds the engine running
(println "started is" (start-engine car))
(stop-engine car)