Makes perfect sense. Thanks! On Mon, Aug 29, 2016 at 5:09 PM Jonathan Fischer <jonat...@mohiji.org> wrote:
> 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 a topic in the > Google Groups "Clojure" group. > To unsubscribe from this topic, visit > https://groups.google.com/d/topic/clojure/LBQ_AELp0Mo/unsubscribe. > To unsubscribe from this group and all its topics, send an email to > clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. > -- Jonathon McKitrick -- 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.