Why are clojure protocol methods often wrapped by functions?

clojure, clojurescript, protocols

Solution

Protocols represent an interface point between two kinds of concrete entities. One is the code calling the protocol (anything that calls `foo` in your example), the other is the code implementing it (`Atype` `foo-method`). What is convenient for one may not be convenient for the other. An implementer wants to provide the smallest interface that is complete, while callers want the richest API that can be supported.

You mentioned ClojureScript core; take a look at the `ISeq` protocol there. It is implemented by several types, each of which must implement `-first` and `-rest`. To make these as easy as possible to implement, neither is required to call seq on its arg. However, the related functions `first` and `rest` that face callers support passing in non-seqs like strings, vectors, etc. so this common functionality is provided by the non-protocol functions.Of course the caller-facing API is even richer than that with `next`, `map`, `filter`, sequential destructuring, etc all built on top of `-first` and `-rest`.

Other common features provided by fns that wrap protocol methods include argument validation (such as asserts), default arguments, and support for var-args.

Problem

Often when I see clojure protocols in a library, the protocol methods will be wrapped in a function, often with little added functionality. e.g.: ``` (defprotocol Pfoo (foo-method [this])) (deftype Atype [x y] Pfoo (foo-method [this] (do-something))) (defn foo [arg] (foo-method arg)) ``` And clients are generally expected to call the function foo, rather than the foo-method from the protocol. (See the protocols at the top of clojurescript core for concrete examples of this kind of thing. So why are protocols often shielded behind functions? Couldn't the protocol method become the client-facing part, rather than the wrapping function?

Original source