Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8697879
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T01:37:19+00:00 2026-06-13T01:37:19+00:00

Firstly, I’m new to Clojure, so this is likely to be stupid question. As

  • 0

Firstly, I’m new to Clojure, so this is likely to be stupid question.

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.

Is defrecord the way to go here?

The question: Can I use Clojure's derive to create a hierarchy of my defrecord class types? seem similar to this, but the accepted answer says ‘no, perhaps use interfaces’.

Is the answer really no? Do I have to write all the data representations as Java classes in order to use Clojure’s multimethods?

Thanks,

Chris.

Working 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")

Below, is what I’ve tried so far, but I get an error at the first derive:

ClassCastException java.lang.Class cannot be cast to clojure.lang.Named clojure.core/namespace (core.clj:1496).

(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)
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T01:37:20+00:00Added an answer on June 13, 2026 at 1:37 am

    The unhappy answer, as @Arthur and @noahz mentioned, is that hierarchies can’t be described with classes. Where does that leave us with multimethods?

    The best answer might be including a :type key in simple maps and dispatching on that value. You lose things like the auto-generated constructor afforded by protocols, but it’s a very straightforward solution and it offers a lot of flexibility.

    (def sword {:type ::weapon, :name "sword", :damage 10})
    (def apple {:type ::item, :name "apple"})
    (def cupboard {:type ::furniture, :name "cupboard"})
    (def bag {:type ::bag, :name "bag"})
    
    (derive ::weapon ::item)
    (derive ::container ::item)
    (derive ::bag ::container)
    (derive ::furniture ::container)
    
    ; dispatch on [type-of-src type-of-dst]
    (defmulti putin (fn [src dst] [(src :type) (dst :type)]))
    (defmethod putin [::item ::container] [src dst] :success_0)
    
    (println (putin sword bag)) ; :success_0
    

    An alternative, albeit one that suffers from over-complication, is to create a map of classes to keywords and use this to look up keywords in the hierarchy when dispatching. Again, I’ll stress that you can probably find something better, but the option is there.

    ; used to look up the keywords associated with classes
    (def class-keyword-map (atom {}))
    
    ; get the keyword associated with an instance's class
    (defn class-keyword
      [instance]
      (@class-keyword-map (class instance)))
    
    ; this macro defines a record as normal
    ; however, after defining the record,
    ; it associates the record's type with
    ; a keyword generated by the record name
    (defmacro def-adventure-record
      [clazz & body]
      `(do
         ; create the record as normal
         (defrecord ~clazz ~@body)
         ; and add the type to the keyword lookup
         (swap!
           class-keyword-map
           assoc ~clazz (keyword (str *ns*) (str '~clazz)))))
    
    (def-adventure-record Item [name])
    (def-adventure-record Weapon [name, damage])
    (def-adventure-record Furniture [name])
    (def-adventure-record Container [name])
    (def-adventure-record Bag [name])
    
    ; we still need to use keywords,
    ; but at this point, they've been
    ; generated for us by the macro above
    (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"))
    
    ; this dispatch is done on the class's keywords
    (defmulti putin (fn [src dst] [(class-keyword src) (class-keyword dst)]))
    
    ; again, keywords describe the multimethod
    (defmethod putin [::Item ::Container] [src dst] :success_0)
    
    (println (putin sword bag)) ; :success_0
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Firstly, I'm new to Python, Qt and PySide so forgive me if this question
Firstly sorry if this is a common question but I couldn't find anything on
Firstly, I know this [type of] question is frequently asked, so let me preface
Firstly, I don't know what the most appropriate title for this question would be.
Firstly I realise that this is a familiar question, it seems to pop up
Firstly, this is a homework assignment, and I am very new to programming in
Firstly my maths is limited, so this question may have a simple answer. So,
Firstly, thanks for taking the time to read and possibly comment on this question.
Firstly, very sorry if this is not a true stackoverflow question. But it's something
Firstly, I want to restrict this question to web development only. So this is

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.