On Dec 11, 11:44 pm, ataggart <alex.tagg...@gmail.com> wrote: > On Dec 11, 4:14 pm, Jason Wolfe <jawo...@berkeley.edu> wrote: > > > > > > > I've been trying out the new branch, and on the whole I like it a lot. > > I know it'll take some time to learn how do things properly the "new" > > way, and I've figured out how to do most of the things I want to do > > thus far. Thanks, Rich! > > > One thing I haven't figured out how to do cleanly without inheritance > > is to specify "properties" of objects in a hierarchical domain in a > > clean, efficient way. I'm sure I haven't fully wrapped my head around > > the new abstractions, so I'd love to hear about a clean way to solve > > this problem. > > > A very simple example is: I have a protocol "A", and sub-protocols > > "A1" and "A2". Every A is either an A1 or A2, but not both (and this > > split is closed, as far as I'm concerned). Sometimes I want to deal > > with instances of A1 and A2 together, and so I put the methods shared > > between all "As" in protocol "A". But, at some point I need to > > separate out the "A1"s from the "A2"s. To do this, it seems like I > > have at least three options: > > > 1. Add an "is-A1" method to Protocol A. The problem with this option > > is that every type that derives from A1 needs to manually write out > > this method returning "true", and vice-versa for implementers of A2. > > Users could eliminate this by "extending" their types with a mixin map > > to A, rather than implementing it directly in the deftype. But, this > > sacrifices readability (IMO) as well as efficiency. > > > 2. use (satisfies? A1 x) to determine if x satisfies A1. The main > > problem with this, at least currently, is that satisfies? seems to be > > really slow in the negative case. I profiled my (non-trivial) program > > and half the runtime was going to reflection in satisfies? Moreover, > > this solution is not as general. > > > 3. Use a multimethod. This would work generally and be reasonably > > efficient, but I feel like I'd be cluttering up my interface by mixing > > up protocols and multimethods. On the other hand, I guess > > multimethods are the main (only?) hierarchical construct built into > > Clojure, so maybe this is what's intended. > > > So, which do people feel is preferred? Or have I missed a better > > option? > > > Thanks! > > Jason > > If I understand Rich's reasoning, what you want runs antithetical to > the protocols design, namely it being explicitly non-hierarchical. > > As such, you'd instead have 3 composable protocols, A, B, and C (where > B and C would correspond to the functions of A1 and A2, respectively): > > (defprotocol A (a [x])) > (defprotocol B (b [x])) > (defprotocol C (c [x])) > > And then the type would reify the appropriate protocols: > > (deftype A1 [] A B > (a [] (println "in A1.a")) > (b [] (println "in A1.b"))) > > (deftype A2 [] A C > (a [] (println "in A2.a")) > (c [] (println "in A2.c")))
I should also note that isa? can be used for differentiation: user=> (def my-a (A1)) #'user/my-a user=> (isa? (type my-a) ::A1) true user=> (isa? (type my-a) ::A2) false -- 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