title: Clojure allows encapsulation and inheritance, but can I combine them?
body: <p>Here is an overly simplistic example for illustration:</p>
  
  <p>I can encapsulate an implementation detail such as using an atom for a counter:</p>
  
  <pre><code>(defn make-counter
    ([] (make-counter 0))
    ([init-val]
     (let [c (atom init-val)]
       {:get (fn [] @c)
        :++ (fn [] (swap! c inc))})))
  </code></pre>
  
  <p>But that means I need to redefine everything to add a feature (no inheritance):    </p>
  
  <pre><code>(defn make-bi-counter
    ([] (make-bi-counter 0))
    ([init-val]
     (let [c (atom init-val)]
       {:get (fn [] @c)
        :++ (fn [] (swap! c inc))
        :-- (fn [] (swap! c dec))})))
  </code></pre>
  
  <p>Whereas if it were possible to just extend the one function:</p>
  
  <pre><code>(assoc c :-- (env (:++ c) (fn [] (swap! c dec))))
  
  (def c (make-counter))
  (def b (make-bi-counter))
  user=&gt; ((:-- b))
  -1
  user=&gt; ((:-- b))
  -2
  user=&gt; ((:get b))
  -2
  </code></pre>
  
  <p>Or I could have just exposed the atom and had independent functions:</p>
  
  <pre><code>(defn -- [a] (swap! a dec))
  (def a (atom 0))
  (-- a)
  </code></pre>
  
  <p>It appears the best option is to forgo encapsulation, if 'inheritance' (or perhaps more accurately: extension) is desirable.</p>