What does extend-protocol do?
A protocol is an abstract thing that looks like an interface in Java. It does nothing, but some other entities may implement it. In Java, you declare a class that implements an interface. In Clojure, you extend a
particular protocol with a custom type declared either with deftype
or defrecord
calling extend-protocol
on it.
When extending a protocol with a type, you need to specify implementation for signatures mentioned in that protocol.
A good example might be JSON serialization. Say, the protocol would look like as follows:
(defprotocol JSON
(to-json [obj]))
If you call (to-json ...)
on any value, you'll have an error saying that there is no to-json
implementation for that type. You need to extend it:
(extend-protocol JSON
Integer
(to-json [obj] (str obj))
Boolean
(to-json [obj]
(if obj "true" "false")))
Now that, calling (to-json 42)
and (to-json false)
will work. You may extend that protocol for the rest of types: floats, array, maps and so on.
what is op in the Protocol
Protocols do not have implementations, only signatures. os
is a signature of some function that just takes three arguments: [gen test process]
. It's up to what should it return. As an example, you may refer the line #46 where its behavior is implemented for the clojure.lang.AFunction
type. Since I'm not familiar with jepsen, I cannot say more on that.
What does mix mean in the context
I think its docstring is pretty clear as well as the code is. I takes a collection of gens. If it's empty, the result would be a special Generator instance named void
. It's an anonymous type that extends Generator protocol returning just nil
when calling op
without any computations.
It the gens
are not empty, the code returns an instance of Generator type with such op
implementation that takes a random gen
when executing op
.
Hope that will help.