Re: defmulti and defmethods in separate namespaces without circular references?
I use a lot of multimethods with my framework, Ciste[0] and it can work, the only thing is you have to be very careful about what you put where, and it helps to have a lot of namespaces. What I do is try to keep all of my defmulti's in one namespace and have only defmethod's in another namespace. Originally, I had one master namespace that required all of the defmethod namespaces (my routes namespace) and then all my "action" namespaces only require the defmulti namespaces. I've since then moved on to use the 'definitializer' functionality of Ciste to require those defmethod namespaces after all of the other namespaces have been required. I'm not saying it's the best coding style, but it works for me and my applications. Be prepared to move functions around a lot to always stay one step ahead of the dreaded cyclic dependency horror. 0: https://github.com/duck1123/ciste On 03/02/2012 10:55 AM, Cymen Vig wrote: > On Friday, March 2, 2012 7:03:10 AM UTC-6, tim.visher wrote: > > I will not in any way claim to know how or why this works. I'm just > starting to use multimethods myself, but I'll give you my set up that > appears to be working at the moment. > > I have a namespace: > > (ns store.store) > > (defmulti serialize method) > > (defmulti slurp method) > > in store.clj > > I have 1 implementation: > > (ns store.file-system > [:use [store.store]] > …) > > (def base "") > > (defmethod serialize :file-system [_ file-name contents] > (fs-utils/write-to contents (str base "/" file-name))) > > (defmethod slurp :file-system [_ file-name] > (clojure.core/slurp (str base "/" file-name))) > > I then use this from another namespace, requiring store.store and > store.store.file-system: > > (ns library > [:require [wallpaper-manager-core.store.file-system :as > store-file-system]] > [:require [wallpaper-manager-core.store.store :as store]]) > > (binding [store-file-system/base (fs/home)] > (def library (ref (read-library) :validator library-validator))) > > (defn serialize-library [library] > (store/serialize :file-system "library.clj" library)) > > And this all seems to work fine for me. Maybe someone else can explain > why it does for me and doesn't for you. Maybe it has something to do > with `use` vs. `require`? > > This does indeed work for me. What I was trying to do was avoid was > having to do this part: > >... > [:require [wallpaper-manager-core.store.store :as store]]) > > As each time I add a defmethod implementation of my defmulti I'd have > to add another require. But maybe that isn't such a bad thing so I'll > go with this approach. I prefer it over having a "super parent (*)" > namespace unless i needed that "super parent" in multiple places. > > * by "super parent" I mean a namespace that is only used to include > the namespaces that contain the defmulti and defmethods > > Thanks, > Cymen > -- > 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 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
Re: defmulti and defmethods in separate namespaces without circular references?
On Friday, March 2, 2012 7:03:10 AM UTC-6, tim.visher wrote: > > I will not in any way claim to know how or why this works. I'm just > starting to use multimethods myself, but I'll give you my set up that > appears to be working at the moment. > > I have a namespace: > > (ns store.store) > > (defmulti serialize method) > > (defmulti slurp method) > > in store.clj > > I have 1 implementation: > > (ns store.file-system > [:use [store.store]] > …) > > (def base "") > > (defmethod serialize :file-system [_ file-name contents] > (fs-utils/write-to contents (str base "/" file-name))) > > (defmethod slurp :file-system [_ file-name] > (clojure.core/slurp (str base "/" file-name))) > > I then use this from another namespace, requiring store.store and > store.store.file-system: > > (ns library > [:require [wallpaper-manager-core.store.file-system :as > store-file-system]] > [:require [wallpaper-manager-core.store.store :as store]]) > > (binding [store-file-system/base (fs/home)] > (def library (ref (read-library) :validator library-validator))) > > (defn serialize-library [library] > (store/serialize :file-system "library.clj" library)) > > And this all seems to work fine for me. Maybe someone else can explain > why it does for me and doesn't for you. Maybe it has something to do > with `use` vs. `require`? > This does indeed work for me. What I was trying to do was avoid was having to do this part: ... [:require [wallpaper-manager-core.store.store :as store]]) As each time I add a defmethod implementation of my defmulti I'd have to add another require. But maybe that isn't such a bad thing so I'll go with this approach. I prefer it over having a "super parent (*)" namespace unless i needed that "super parent" in multiple places. * by "super parent" I mean a namespace that is only used to include the namespaces that contain the defmulti and defmethods Thanks, Cymen -- 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
Re: defmulti and defmethods in separate namespaces without circular references?
I built a modeling system that uses the multi-method namespace separation you are talking about. The solution that I use simply leverages the difference between require, use, and refer. In each namespace that implements the multi-method, put (refer 'parent) after the ns form. In the parent namespace wait until the end of the file and place (require 'child1 'child2 ...). Good luck, ~Gary -- 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
Re: defmulti and defmethods in separate namespaces without circular references?
On Thu, Mar 1, 2012 at 8:33 PM, Cymen Vig wrote: > I attempted to do something like this: > > (ns parent) > (defmulti my-method (fn [x] (:method x)) > > (ns child1) > (defmethod my-method :zzz > ...) > > (ns child2) > (defmethod my-method :aaa > ...) > > However the problem is the children need to use the parent namespace in > order to have the method definition and the code that uses all of this needs > to use all the namespaces too. This creates a circular reference and > compilation fails. I will not in any way claim to know how or why this works. I'm just starting to use multimethods myself, but I'll give you my set up that appears to be working at the moment. I have a namespace: (ns store.store) (defmulti serialize method) (defmulti slurp method) in store.clj I have 1 implementation: (ns store.file-system [:use [store.store]] …) (def base "") (defmethod serialize :file-system [_ file-name contents] (fs-utils/write-to contents (str base "/" file-name))) (defmethod slurp :file-system [_ file-name] (clojure.core/slurp (str base "/" file-name))) I then use this from another namespace, requiring store.store and store.store.file-system: (ns library [:require [wallpaper-manager-core.store.file-system :as store-file-system]] [:require [wallpaper-manager-core.store.store :as store]]) (binding [store-file-system/base (fs/home)] (def library (ref (read-library) :validator library-validator))) (defn serialize-library [library] (store/serialize :file-system "library.clj" library)) And this all seems to work fine for me. Maybe someone else can explain why it does for me and doesn't for you. Maybe it has something to do with `use` vs. `require`? > 1) Is it a bad idea to try to put the defmulti and defmethods into separate > namespaces? I don't personally see it as a bad idea, simply because I see defmulti as a nice, clean way of defining an Interface with multiple implementations to choose from. One of the ways that I'm using it it to implement my html vs. json routes. I'm hoping that I can have a route1.json namespace for all of the json requests and route1.html for all the html requests. Based on my success with the store namespace I don't foresee this being a problem, but maybe it will. I heavily edited the code to remove uninteresting bits and I didn't test it so be aware of that. :) Hope that helps! -- In Christ, Timmy V. http://blog.twonegatives.com/ http://five.sentenc.es/ -- Spend less time on mail -- 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