Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are clojure protocol methods often wrapped by functions?

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?

like image 486
Rob Lachlan Avatar asked Mar 28 '13 04:03

Rob Lachlan


1 Answers

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.

like image 127
Chouser Avatar answered Oct 01 '22 09:10

Chouser