Protocols and Records

What are protocols?

Clojure is a language that coexists in terms of abstractions with many implementations for them. In an object-oriented programming language, we know those abstractions as interfaces, and we’re able to implement and modify the algorithm for each implementation as many times as we want.

Protocols are the available features for abstraction and data structure definition with no compromises. They are essentially a collection of one or more polymorphic operations. Unlike multimethods (also of the polymorphism family), which perform dispatch on arbitrary values returned by a dispatching function, protocol methods are dispatched based on the type of the first argument.

Advantages

There are a number of reasons for using protocols:

  • They provide high-performance polymorphism as an alternative to interfaces.

  • Multiple protocols can be created with a single type.

  • They support the great majority of multimethod cases while providing higher-level abstraction/organization.

  • Their usage is the most common way to allow state management.

Disadvantages

In comparison with multimethods, the only disadvantages that can be taken into consideration are that they’re less versatile and their usability with the REPL is unfavorable. That’s because, unlike other JVM interop, they don’t reload as well as other constructs, which makes the REPL break when using them.

Defining a protocol

Clojure has the defprotocol function that allows us to define our protocol. It also generates a few effects in our code:

  • A variable with the name defined in the protocol will be fixed in the namespace, so it won't reload. This is also known as a defonce, so it’s defined one time only. The name of the protocol is normally written with the first letter in uppercase—for instance, Dog.

  • An immutable map with protocol information will be built and bound to a variable name using the defonce function, provided the name doesn’t already have a root value.

  • A Java interface with protocol methods and their signatures will be dynamically generated and loaded into the class loader. So, we have a close connection to the object-oriented programming interface.

Now let’s see how we define it. We’ll use the famous example of dogs and their abilities:

Get hands-on with 1200+ tech skills courses.