I read too quickly. I might need multi-methods after all, just like I used in Common Lisp. I want different types of persisted objects to have the same interface, if possible.
Actually, I'm just experimenting with protocols, so I'm probably better off looking for a different use case. On Mon, Aug 29, 2016 at 5:11 PM <jmckitr...@gmail.com> wrote: > 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 > -- 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.