Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save christianromney/a85c8fce1fb639bbffcc to your computer and use it in GitHub Desktop.
Save christianromney/a85c8fce1fb639bbffcc to your computer and use it in GitHub Desktop.

Clojure does Objects Better

A hopefully short and concise explanation as to how Clojure deals with Objects. If you already write Clojure, this isn't for you.

You know what an Interface is if you write/read Java or PHP 5+. In Clojure it might be called defprotocol.

user> (defprotocol IABC
        (also-oo [this])
        (another-fn [this x]))
IABC

You might be tempted to use the classic implements or extends keywords when defining a new Class. In Clojure it might be called defrecord.

user> (defrecord ABC [name]
        ;; You can implement multiple Interfaces/Protocols here
        IABC
        (also-oo [this]
          (str "This => " (:name this)))
        (another-fn [this x]
          (format "%s says: %s" (:name this) x)))
user.ABC

You might be tempted to use the classic new keyword to instantiate a new object. In Clojure it might be a simple decimal suffix added to the Class name so that it can be used as a predicate.

user> (def a (ABC. "Roger"))
#'user/a
user> (another-fn a "oo programing")
"Roger says: oo programing"
user> (also-oo a)
"This => Roger"

Clojure can just do it better.

user> (defmulti this-is-oo type)
nil
user> (defmethod this-is-oo ABC [this]
        (println (:name this)))
#<MultiFn clojure.lang.MultiFn@8625d0e>
user> (this-is-oo a)
Roger
user> (defmethod this-is-oo java.lang.String [this]
        "Got a string and not ABC!!!!")
#<MultiFn clojure.lang.MultiFn@8625d0e>
user> (this-is-oo "a")
"Got a string and not ABC!!!!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment