The most straightforward one: just make your protocols a thing that your storage medium implements, instead of your records. E.g.:
(defprotocol ThingStore (load-item [store item-id]) (load-items [store item-ids]) (find-item [store item-name]) (save-item [store item])) (defrecord DatabaseStore ThingStore (load-item [store item-id] ...)) Otherwise, Clojure does have multimethods, but the dispatch mechanism doesn't work the same was as Common Lisp's. You could probably combine multimethods with a marker protocol to do what you're trying. ;; First, an empty marker protocol (defprotocol Loadable) ;; And something that you want to load (defrecord Thing [data] Loadable ;; mark that it implements that empty protocol ) ;; Define a multimethod dispatch function that will figure out the right implementation to call (defn loadable-dispatch [item] (cond (satisfies? Loadable item) ::load-one-item (and (sequential? item) (every? #(satisfies? Loadable %) item)) ::load-many-items :else nil)) ;; The multimethod itself (defmulti load-item loadable-dispatch) ;; And implementations (defmethod load-item ::load-one-item [item] "Load one item.") (defmethod load-item ::load-many-items [items] "Load many items.") user> (load-item (map->Thing {})) "Load one item." user> (load-item [(map->Thing {}) (map->Thing {})]) "Load many items." Overall, you're probably better off with the first option, but you can make multimethods work for you here if you want. On Sunday, August 28, 2016 at 7:29:46 AM UTC-7, Jonathon McKitrick wrote: > > I'm beginning a foray into protocols after coming from the Common Lisp > world of multimethods. I'm using them initially to implement a consistent > load/save API over the DB layer. > > It's pretty simple to have a Saveable protocol to save one object, because > the first argument is a Record of the type I am saving. > > But since protocols dispatch on the first argument, how do you define a > Loadable protocol that loads an object or handles a collection of objects? > > For example, if I want to load an object by idx, the first argument is not > a Record, but an integer, or perhaps an arbitrary field to used in a query. > > > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.