title: Clojure multimethods, how to add data?
body: <p>Firstly, I'm new to Clojure, so this is likely to be stupid question.</p>
  
  <p>As a learning exercise, I've got a trivial text adventure multimethod system working.  I now want to change from using keywords to some form of 'classiness', which can hold data pertaining to the individual instances of 'sack', 'sword', etc.</p>
  
  <p>Is <code>defrecord</code> the way to go here?</p>
  
  <p>The question: <a href="https://stackoverflow.com/questions/4586608/can-i-use-clojures-derive-to-create-a-hierarchy-of-my-defrecord-class-types">Can I use Clojure&#39;s derive to create a hierarchy of my defrecord class types?</a> seem similar to this, but the accepted answer says 'no, perhaps use interfaces'.  </p>
  
  <p>Is the answer really no?  Do I have to write all the data representations as Java classes in order to use Clojure's multimethods?</p>
  
  <p>Thanks,</p>
  
  <p>Chris.</p>
  
  <p>Working code:</p>
  
  <pre><code>(derive ::unlit_root ::room)
  (derive ::room ::thing)
  (derive ::item ::thing)
  (derive ::sword ::item)
  (derive ::container ::thing)
  (derive ::sack ::container)
  (derive ::sack ::item)
  (derive ::wardrobe ::furniture)
  (derive ::furniture ::thing)
  (derive ::wardrobe ::furniture)
  
  (defmulti put (fn [x y z] [x y z]))
  (defmethod put [::room ::thing ::thing] [x y z] "you can only put items into containers")
  (defmethod put [::room ::sword ::sack] [x y z] "the sword cuts the sack")
  (defmethod put [::room ::item ::container] [x y z] "ordinary success")
  (defmethod put [::unlit_room ::thing ::thing] [x y z] "it's too dark, you are eaten by a grue")
  (defmethod put [::room ::sack ::wardrobe] [x y z] "you win")
  (defmethod put [::room ::item ::sack] [x y z] "you put it in the sack")
  (defmethod put [::room ::furniture ::thing] [x y z] "it's too big to move")
  </code></pre>
  
  <p>Below, is what I've tried so far, but I get an error at the first <code>derive</code>: </p>
  
  <p><code>ClassCastException java.lang.Class cannot be cast to clojure.lang.Named  clojure.core/namespace (core.clj:1496)</code>.</p>
  
  <pre><code>(defrecord Item [name])
  (defrecord Weapon [name, damage])
  (defrecord Furniture [name])
  (defrecord Container [name])
  (defrecord Bag [name])
  (derive Weapon Item)
  (derive Container Item)
  (derive Bag Container)
  (derive Furniture Container)
  
  (def sword (Weapon. "sword" 10))
  (def apple (Item. "apple"))
  (def cupboard (Furniture. "cupboard"))
  (def bag (Bag. "bag"))
  
  
  (defmulti putin (fn [src dst] [src dst]))
  (defmethod putin [Item Container] [src dst] :success_0)
  </code></pre>