Skip to content

Instantly share code, notes, and snippets.

@esshka
Forked from david-mcneil/inheritance.clj
Created February 16, 2016 18:14
Show Gist options
  • Save esshka/545cb1f4c9e20e4e8fec to your computer and use it in GitHub Desktop.
Save esshka/545cb1f4c9e20e4e8fec to your computer and use it in GitHub Desktop.
Demonstration of implementation "inheritance" in clojure
;; Define a "base type" of Dog
(defrecord Dog [breed])
;; Define a "sub type" of TrainedDog
(defrecord TrainedDog [dog word])
;; The interface that both Dog and TrainedDog will implement
(defprotocol Talker
(bark [_])
(speak [_])
(to-dog [_]))
;; The base behavior that will be used for Dogs and TrainedDogs
(def base-behavior {:bark (fn [doggable]
(str "arf (" (:breed (to-dog doggable)) ")"))
:speak (fn [doggable]
(bark doggable))
:to-dog (fn [dog] dog)})
;; Use the base behavior as the implmentation of the Dog Talker behavior.
(extend Dog
Talker
base-behavior)
(def fido (Dog. "collie"))
(bark fido)
;; => "arf (collie)"
(speak fido)
;; => "arf (collie)"
;; For the TrainedDog, start with the base-behavior but "override" two
;; of the functions with alternate behavior.
(extend TrainedDog
Talker
(merge base-behavior
{:speak (fn [trained-dog] (str (:word trained-dog)))
:to-dog (fn [trained-dog] (:dog trained-dog))}))
(def rex (TrainedDog. (Dog. "yorkie") "hello"))
;; TrainedDogs use the 'bark' implementation from the base-behavior
(bark rex)
;; => "arf (yorkie)"
;; TrainedDogs use their own 'speak' implementation
(speak rex)
;; => "hello"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment