Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojure, Aspects, Defprotocol, Defrecord

Tags:

clojure

(defprotocol IAnimal "IAnimal"
  (report [o]
    (println (type o) " reporting.\n")
    (inner-report o)
    (println (type o) " out.\n")))

(defrecord Dog [] IAnimal
  (inner-report [o]
    (println "Woof Woof.\n")))

(defrecord Cat [] IAnimal
  (inner-report [o]
    (println "Meow Meow.\n")))

(defrecord Vampire [] IAnimal
  (inner-report [o]
    (println "I don't sparkle.\n")))

Now, I would like it to output:

Dog reporting.
Woof Woof.
Dog out.
Cat reporting.
Meow Meow.
Cat out.
Vampire reporting.
I don't sparkle.
Vampire out.

Unfortuantely, this does not happen since the above code does not compile. What is the best way to achieve "this" ?

Where by "this", I mean I have some function that I want to be part of a protocol, I want to have one implementation of it for all records, and I want this function to have access to specialized functions that records implement.

(What is the clojure way of doing this?)


1 Answers

Protocols are like Java interfaces, they cannot provide implementation for their methods. But this works:

(defn report [o]
  (println (type o) " reporting.\n")
  (inner-report o)
  (println (type o) " out.\n"))

(defprotocol IAnimal
  "the animal protocol"
  (inner-report [o] "a report"))

(defrecord Dog []
  IAnimal
  (inner-report [o]
    (println "Woof Woof.\n")))

(defrecord Cat []
  IAnimal
  (inner-report [o]
    (println "Meow Meow.\n")))

(defrecord Vampire []
  IAnimal
  (inner-report [o]
    (println "I don't sparkle.\n")))

(report (new Cat))
;; user.Cat reporting.
;; Meow Meow.
;; user.Cat out.
like image 77
Jean-Louis Giordano Avatar answered Mar 10 '26 12:03

Jean-Louis Giordano



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!