Performance Gotcha
The performance of Clojure protocols is a bit nuanced. A Clojure protocol generates a Java interface, a protocol, and some protocol functions. The protocol functions will dispatch through the Java interface if the type of the first argument implements the interface; otherwise, it will dispatch through the protocol's dispatch table.
There are two ways to implement a protocol in Clojure:
1 (defrecord S3Storage
2 [access-key secret-key]
3 proto/IStorage
4 ...)
Or:
1 (defrecord S3Storage
2 [access-key secret-key])
3
4 (extend-protocol IStorage
5 S3Storage
6 ...)
Conceptually, these seem as though they are equivalent, but they are not. The first example, extending the protocol directly in the defrecord form, will be around 20 times faster! When you extend a protocol inside of a defrecord, the generated class will implement the protocol's...