3

A record can implement protocols. However, each time I think of a new function that I would like the record to implement, I have to add it to an existing protocol or create a new protocol. How do I get around this? Ideally, I'd just like to associate a function to a record without having to define a protocol.

2 Answers 2

2

Then just write a function that takes an instance of that record as an argument.

defrecord doesn't "implement" a protocol, in the sense that class in a Java-like OO language implements an interface. What it does is define a datatype, and give you some syntactic sugar to implement a protocol that operates on that datatype. There's a pretty great overview of just what sort of problem protocols are meant to solve here - http://www.ibm.com/developerworks/library/j-clojure-protocols/

2

Excellent question. Here's an answer based on a similar one I gave on StackOverflow.

As usual, there's a beautiful way to do things in Clojure - here's how to implement your own simple dynamic OO system (including inheritance, polymorphism and encapsulation) in 10 lines of Clojure.

The idea: You can put functions inside normals Clojure maps or records if you want, creating an OO-like structure. You can then use this in a "prototype" style.

; define a prototype instance to serve as your "class"
; use this to define your methods, plus any default values
(def person-class
  {:get-full-name 
    (fn [this] (str (:first-name this) " " (:last-name this)))})

; define an instance by merging member variables into the class
(def john 
  (merge person-class 
    {:first-name "John" :last-name "Smith"}))

; macro for calling a method - don't really need it but makes code cleaner
(defmacro call [this method & xs]
  `(let [this# ~this] ((~method this#) this# ~@xs)))

; call the "method"
(call john :get-full-name)
=> "John Smith"

; added bonus - inheritance for free!
(def mary (merge john {:first-name "Mary"}))
(call mary :get-full-name)
=> "Mary Smith"
2
  • hmm just realised I've posted the same answer to the same poster on both StackOverflow and Programmers..... ah well, guess that both sites have audiences that would be interested!
    – mikera
    Feb 17, 2011 at 11:19
  • See also github.com/Prismatic/eng-practices/blob/master/clojure/… for an in depth discussion of the topic including the desugared version of the call macro syntax from mikera's answer.
    – John
    Nov 30, 2013 at 11:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.