What is reify in Clojure?

reify is to defrecord what fn is to defn.
“Ah right…… so what’s reify

Put simply, protocols are lists of functions a datatype should support, records are datatypes and reifications are anonymous datatypes.

Maybe this is long-winded, but reify can’t be understood concretely without understanding protocols and types/records: Protocols are a way to use the same name for a function such as conj that actually acts differently when given different arguments ((conj [:b :c] :a) => [:b :c :a] but (conj '(:b :c) :a) => (:a :b :c)). Records are like objects or types (but they act like maps making them awesomer).

More fundamentally, the goal is to solve “The Expression Problem” that is to have the ability to seamlessly add new types of data that work with existing functions, and new functions that work seamlessly with existing data.

So one day you say to yourself, “Self, you should learn what it means to be a duck!” so you write a protocol:

(defprotocol Quacks
  (quack [_] "should say something in ducky fashion"))

But it’s all too abstract so you ‘realify’ it:

(def donald (reify Quacks
                   (quack [_] "Quacks and says I'm Donald")))

Now at last you can experience your creation:

(quack donald) => "Quacks and says I'm Donald"

Then you remember about Daffy:

(def daffy (reify Quacks
                  (quack [_] (str "Quacks and says I'm Daffy"))))

(quack daffy) => "Quacks and says I'm Daffy"

But by the time you remember about Huey, you realize your mistake and define what a duck is in a reusable way:

(defrecord Duck [name]
  Quacks
  (quack [_] (str "Quacks and says I'm " name)))

And make new ducks (there are several ways to do it):

(def huey (->Duck "Huey"))
(def duey (Duck. "Duey"))
(def louie (new Duck "Louie"))

(quack huey) => "Quacks and says I'm Huey"

Remember that records act like maps (thank to protocols!):

(:name huey) => "Huey"

But then you remember that ducks must quack and walk so you write another protocol:

(defprotocol Walks
  (walk [_] "should walk like a duck"))

And extend the definition of duck

(extend-type Duck
  Walks
  (walk [_] "waddle waddle"))

(walk louie) => "waddle waddle"

Now we can extend other types to implement the same protocol (teach the same function how to work with other things):

So let’s say we want programmers to quack too 🙂

(defrecord Programmer [] Quacks
  (quack [_] "Monads are simply monoids in a category of endofunctors..."))

(quack (Programmer.)) => "Monads are simply monoids in a category of endofunctors..."

I recommend this great explanation of protocols, an explanation of reify and a chapter on protocols in “Clojure for the Brave and True”.

Disclaimer: This is only meant to give an initial understanding of what protocols are, not best practices on how to use them. “Psst! I answered this question largely to teach myself, because until yesterday I had never actually written my own protocol/interface!”

So while I hope that it enhances someone else’s learning, I’ll heartily welcome criticism or edit-suggestions!”.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)